欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python技法之如何用re模塊實(shí)現(xiàn)簡(jiǎn)易tokenizer

 更新時(shí)間:2022年05月01日 08:36:28   作者:orion-orion  
當(dāng)我們?cè)赑ython中開始新的東西時(shí),我通常首先看一些模塊或庫來使用,下面這篇文章主要給大家介紹了關(guān)于Python技法之如何用re模塊實(shí)現(xiàn)簡(jiǎn)易tokenizer的相關(guān)資料,需要的朋友可以參考下

一個(gè)簡(jiǎn)單的tokenizer

分詞(tokenization)任務(wù)是Python字符串處理中最為常見任務(wù)了。我們這里講解用正則表達(dá)式構(gòu)建簡(jiǎn)單的表達(dá)式分詞器(tokenizer),它能夠?qū)⒈磉_(dá)式字符串從左到右解析為標(biāo)記(tokens)流。

給定如下的表達(dá)式字符串:

text = 'foo = 12 + 5 * 6'

我們想要將其轉(zhuǎn)換為下列以序列對(duì)呈現(xiàn)的分詞結(jié)果:

tokens = [('NAME', 'foo'), ('EQ', '='), ('NUM', '12'), ('PLUS', '+'),\
    ('NUM', '5'), ('TIMES', '*'), ('NUM', '6')]

要完成這樣的分詞操作,我們首先需要定義出所有可能的標(biāo)記模式(所謂模式(pattern),為用來描述或者匹配/系列匹配某個(gè)句法規(guī)則的字符串,這里我們用正則表達(dá)式來做為模式),注意此處要包括空格whitespace,否則字符串中出現(xiàn)任何模式中沒有的字符后,掃描就會(huì)停止。因?yàn)槲覀冞€需要給標(biāo)記以NAME、EQ等名稱,我們采用正則表達(dá)式中的命名捕獲組來實(shí)現(xiàn)。

import re
NAME = r'(?P<NAME>[a-zA-Z_][a-zA-Z_0-9]*)' 
# 這里?P<NAME>表示模式名稱,()表示一個(gè)正則表達(dá)式捕獲組,合在一起即一個(gè)命名捕獲組
EQ = r'(?P<EQ>=)'
NUM = r'(?P<NUM>\d+)' #\d表示匹配數(shù)字,+表示任意數(shù)量
PLUS = r'(?P<PLUS>\+)' #需要用\轉(zhuǎn)義
TIMES = r'(?P<TIMES>\*)' #需要用\轉(zhuǎn)義
WS = r'(?P<WS>\s+)' #\s表示匹配空格, +表示任意數(shù)量
master_pat = re.compile("|".join([NAME, EQ, NUM, PLUS, TIMES, WS]))  # | 用于選擇多個(gè)模式,表示"或"

接下來我們用模式對(duì)象中的scanner()方法來完成分詞操作,該方法創(chuàng)建一個(gè)掃描對(duì)象:

scanner = master_pat.scanner(text)

然后可以用match()方法獲取單次匹配結(jié)果,一次匹配一個(gè)模式:

scanner = master_pat.scanner(text)
m = scanner.match() 
print(m.lastgroup, m.group()) # NAME foo
m = scanner.match()
print(m.lastgroup, m.group()) # WS

當(dāng)然這樣一次一次調(diào)用過于麻煩,我們可以使用迭代器來批量調(diào)用,并將單次迭代結(jié)果以具名元組形式存儲(chǔ)

Token = namedtuple('Token', ['type', 'value'])
def generate_tokens(pat, text):
    scanner = pat.scanner(text)
    for m in iter(scanner.match, None):
        #scanner.match做為迭代器每次調(diào)用的方法,
        #None為哨兵的默認(rèn)值,表示迭代到None停止
        yield Token(m.lastgroup, m.group())
    
for tok in generate_tokens(master_pat, "foo = 42"):
    print(tok)

最終顯示表達(dá)式串"foo = 12 + 5 * 6"的tokens流為:

Token(type='NAME', value='foo')
Token(type='WS', value=' ')
Token(type='EQ', value='=')
Token(type='WS', value=' ')
Token(type='NUM', value='12')
Token(type='WS', value=' ')
Token(type='PLUS', value='+')
Token(type='WS', value=' ')
Token(type='NUM', value='5')
Token(type='WS', value=' ')
Token(type='TIMES', value='*')
Token(type='WS', value=' ')
Token(type='NUM', value='6')

過濾tokens流

接下來我們想要過濾掉空格標(biāo)記,使用生成器表達(dá)式即可:

tokens = (tok for tok in generate_tokens(master_pat, "foo = 12 + 5 * 6")
          if tok.type != 'WS')
for tok in tokens:
    print(tok)

可以看到空格被成功過濾:

Token(type='NAME', value='foo')
Token(type='EQ', value='=')
Token(type='NUM', value='12')
Token(type='PLUS', value='+')
Token(type='NUM', value='5')
Token(type='TIMES', value='*')
Token(type='NUM', value='6')

注意子串匹配陷阱

tokens在正則表達(dá)式(即"|".join([NAME, EQ, NUM, PLUS, TIMES, WS]))中順序也非常重要。因?yàn)樵谶M(jìn)行匹配時(shí),re模塊就會(huì)按照指定的順序?qū)δJ阶銎ヅ?。故若碰巧某個(gè)模式是另一個(gè)較長模式的子串時(shí),必須保證較長的模式在前面優(yōu)先匹配。如下面分別展示正確的和錯(cuò)誤的匹配方法:

LT = r'(?P<LT><)'
LE = r'(?P<LE><=)'
EQ = r'(?P<EQ>>=)'
master_pat = re.compile("|".join([LE, LT, EQ]))  # 正確的順序
master_pat = re.compile("|".join([LT, LE, EQ]))  # 錯(cuò)誤的順序

第二種順序的錯(cuò)誤之處在于,這樣會(huì)把'<='文本匹配為LT('<')緊跟著EQ('='),而沒有匹配為單獨(dú)的LE(<=)。

我們對(duì)于“有可能”形成子串的模式也要小心,比如下面這樣:

PRINT = r'(?P<PRINT>print)'
NAME = r'(?P<NAME>[a-zA-Z_][a-zA-Z_0-9]*)'

master_pat = re.compile("|".join([PRINT, NAME]))  # 正確的順序

for tok in generate_tokens(master_pat, "printer"):
    print(tok)

可以看到被print實(shí)際上成了另一個(gè)模式的子串,導(dǎo)致另一個(gè)模式的匹配出現(xiàn)了問題:

# Token(type='PRINT', value='print')
# Token(type='NAME', value='er')

更高級(jí)的語法分詞,建議采用像PyParsing或PLY這樣的包。特別地,對(duì)于英文自然語言文章的分詞,一般被集成到各類NLP的包中(一般分為按空格拆分、處理前后綴、去掉停用詞三步驟)。對(duì)于中文自然語言處理分詞也有豐富的工具(比如jieba分詞工具包)。

引用

  • [1] Martelli A, Ravenscroft A, Ascher D. Python cookbook[M]. " O'Reilly Media, Inc.", 2015.

 總結(jié)

到此這篇關(guān)于Python技法之如何用re模塊實(shí)現(xiàn)簡(jiǎn)易tokenizer的文章就介紹到這了,更多相關(guān)Python re模塊實(shí)現(xiàn)tokenizer內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • python利用元類和描述器實(shí)現(xiàn)ORM模型的詳細(xì)步驟

    python利用元類和描述器實(shí)現(xiàn)ORM模型的詳細(xì)步驟

    Python中的類與數(shù)據(jù)庫之間的映射,對(duì)數(shù)據(jù)的操作就不用編寫SQL語言了,因?yàn)槎挤庋b好了,比如你想插入一條數(shù)據(jù),你就直接創(chuàng)建一個(gè)對(duì)象即可,下面通過本文學(xué)習(xí)下python利用元類和描述器實(shí)現(xiàn)ORM模型的詳細(xì)步驟,感興趣的朋友一起看看吧
    2021-11-11
  • Python selenium 加載并保存QQ群成員,去除其群主、管理員信息的示例代碼

    Python selenium 加載并保存QQ群成員,去除其群主、管理員信息的示例代碼

    這篇文章主要介紹了Python selenium 加載并保存QQ群成員 去除其群主、管理員信息的示例代碼,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2020-05-05
  • python中關(guān)于日期時(shí)間處理的問答集錦

    python中關(guān)于日期時(shí)間處理的問答集錦

    python中有關(guān)日期時(shí)間處理的問答集錦,有需要的朋友不妨參考下
    2013-03-03
  • Python用SSH連接到網(wǎng)絡(luò)設(shè)備

    Python用SSH連接到網(wǎng)絡(luò)設(shè)備

    這篇文章主要介紹了Python用SSH連接到網(wǎng)絡(luò)設(shè)備,幫助大家更好的理解和使用python,感興趣的朋友可以了解下
    2021-02-02
  • python操作excel文件并輸出txt文件的實(shí)例

    python操作excel文件并輸出txt文件的實(shí)例

    今天小編就為大家分享一篇python操作excel文件并輸出txt文件的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07
  • django從后臺(tái)返回html代碼的實(shí)例

    django從后臺(tái)返回html代碼的實(shí)例

    這篇文章主要介紹了django從后臺(tái)返回html代碼的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-03-03
  • Python進(jìn)行數(shù)據(jù)提取的方法總結(jié)

    Python進(jìn)行數(shù)據(jù)提取的方法總結(jié)

    數(shù)據(jù)提取是分析師日常工作中經(jīng)常遇到的需求。如某個(gè)用戶的貸款金額,某個(gè)月或季度的利息總收入,某個(gè)特定時(shí)間段的貸款金額和筆數(shù),大于5000元的貸款數(shù)量等等。本篇文章介紹如何通過python按特定的維度或條件對(duì)數(shù)據(jù)進(jìn)行提取,完成數(shù)據(jù)提取需求。
    2016-08-08
  • Django模板變量如何傳遞給外部js調(diào)用的方法小結(jié)

    Django模板變量如何傳遞給外部js調(diào)用的方法小結(jié)

    這篇文章主要給大家介紹了關(guān)于Django模板變量如何傳遞給外部js調(diào)用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編一起來學(xué)習(xí)學(xué)習(xí)吧。
    2017-07-07
  • 可能是最全面的 Python 字符串拼接總結(jié)【收藏】

    可能是最全面的 Python 字符串拼接總結(jié)【收藏】

    在 Python 中字符串連接有多種方式,這里簡(jiǎn)單做個(gè)總結(jié),應(yīng)該是比較全面的了,方便以后查閱,需要的朋友可以參考下
    2018-07-07
  • Python趣味實(shí)戰(zhàn)之手把手教你實(shí)現(xiàn)舉牌小人生成器

    Python趣味實(shí)戰(zhàn)之手把手教你實(shí)現(xiàn)舉牌小人生成器

    前幾天寫了一個(gè)嬰兒級(jí)別的爬蟲圖文教程,大家很喜歡.恰好周末看到有人咨詢這個(gè) “舉牌小人” 怎么做?基于此,我想借此為大家再寫一篇 “爬蟲應(yīng)用” 的文章,教你制作一個(gè)好玩兒的 “舉牌小人” ,需要的朋友可以參考下
    2021-06-06

最新評(píng)論