python re怎么用,python中re库作用
当我们在Python中开始一些新的东西时,我通常首先看一些要使用的模块或库。下面的文章主要介绍一些关于Python技术的信息,以及如何用re模块实现简单的tokenizer。有需要的可以参考一下。
00-1010一个简单的记号赋予器过滤器记号失控含义字符串匹配陷阱引用摘要
目录
分词是Python字符串处理中最常见的任务。这里我们解释如何用正则表达式构建一个简单的记号赋予器,它可以从左到右将表达式字符串解析成记号。
给定以下表达式字符串:
text=foo=12 5 * 6
我们希望将它转换成以下以序列对呈现的分割结果:
令牌=[(NAME , foo ),( EQ ,=),( NUM , 12 ),( PLUS , ),
( NUM , 5 ),( TIMES , *),( NUM , 6)]
要完成这个分词操作,首先需要定义所有可能的标记模式(所谓模式,就是用来描述或匹配/串联某种句法规则的字符串,这里我们用正则表达式作为模式)。注意,这里应该包含空格,否则,在字符串中出现任何不符合模式的字符后,扫描将会停止。因为我们还需要给标签命名,比如NAME,EQ等。我们使用正则表达式中的命名捕获组来实现它。
进口re
NAME=r (?PNAME[a-zA-Z_][a-zA-Z_0-9]*)
#这里?PNAME表示模式的名称,而()表示正则表达式捕获组,它们合起来就是一个命名的捕获组。
EQ=r (?PEQ=)
NUM=r (?PNUMd ) #d表示匹配数,表示任意数。
PLUS=r (?P ) #需要用进行转义。
TIMES=r (?PTIMES*) #需要用进行转义。
WS=r (?PWSs ) #s s表示匹配空格,这意味着任何数字。
Master _ pat=re.pile ( )。join ([name,eq,num,plus,times,ws]) #用于选择多个模式,表示“或”
接下来,我们使用pattern对象中的scanner()方法来完成分词,这将创建一个扫描的对象:
scanner=master_pat.scanner(文本)
然后,您可以使用match()方法获得单个匹配结果,一次匹配一个模式:
scanner=master_pat.scanner(文本)
m=scanner.match()
print(m.lastgroup,m.group()) # NAME foo
m=scanner.match()
print(m.lastgroup,m.group()) # WS
当然一次打一个电话太麻烦了。我们可以使用迭代器进行批量调用,并将单次迭代的结果存储为命名元组。
Token=namedtuple(Token ,[type , value])
def generate _ token(pat,text):
scanner=pat.scanner(文本)
对于iter中的m(scanner . match,None):
#scanner.match作为迭代器每次调用的方法,
#None是sentry的默认值,这意味着迭代在None处停止。
让步令牌(m.lastgroup,m.group())
对于generate_tokens(master_pat, foo=42):中的tok
打印(托克)
显示最终表达式字符串“foo=12 5 * 6”的令牌流为:
令牌(类型=名称,值=foo )
令牌(类型=WS ,值= )
令牌(t
ype=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流
接下来我们想要过滤掉空格标记,使用生成器表达式即可:
tokens = (tok for tok in generate_tokens(master_pat, "foo = 12 + 5 * 6")
可以看到空格被成功过滤:
Token(type=NAME, value=foo)
注意子串匹配陷阱
tokens在正则表达式(即"".join([NAME, EQ, NUM, PLUS, TIMES, WS])
)中顺序也非常重要。因为在进行匹配时,re模块就会按照指定的顺序对模式做匹配。故若碰巧某个模式是另一个较长模式的子串时,必须保证较长的模式在前面优先匹配。如下面分别展示正确的和错误的匹配方法:
LT = r(?P<LT><)
第二种顺序的错误之处在于,这样会把'<='文本匹配为LT('<')紧跟着EQ('='),而没有匹配为单独的LE(<=)。
我们对于有可能形成子串的模式也要小心,比如下面这样:
PRINT = r(?P<PRINT>print)
可以看到被print实际上成了另一个模式的子串,导致另一个模式的匹配出现了问题:
# Token(type=PRINT, value=print)
更高级的语法分词,建议采用像PyParsing或PLY这样的包。特别地,对于英文自然语言文章的分词,一般被集成到各类NLP的包中(一般分为按空格拆分、处理前后缀、去掉停用词三步骤)。对于中文自然语言处理分词也有丰富的工具(比如jieba分词工具包)。
引用
[1] Martelli A, Ravenscroft A, Ascher D. Python cookbook[M]. " O'Reilly Media, Inc.", 2015.
总结
到此这篇关于Python技法之如何用re模块实现简易tokenizer的文章就介绍到这了,更多相关Python re模块实现tokenizer内容请搜索盛行IT软件开发工作室以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT软件开发工作室!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。