在Python中对正则表达式使用compile有什么好处吗?
h = re.compile('hello')
h.match('hello world')
vs
re.match('hello', 'hello world')
在Python中对正则表达式使用compile有什么好处吗?
h = re.compile('hello')
h.match('hello world')
vs
re.match('hello', 'hello world')
当前回答
一般来说,我发现在编译模式时使用标志比内联使用标志更容易(至少更容易记住如何使用),比如re.I。
>>> foo_pat = re.compile('foo',re.I)
>>> foo_pat.findall('some string FoO bar')
['FoO']
vs
>>> re.findall('(?i)foo','some string FoO bar')
['FoO']
其他回答
抛开性能差异不考虑,使用re.compile和使用编译后的正则表达式对象进行匹配(任何与正则表达式相关的操作)使得Python运行时的语义更加清晰。
我有过调试一些简单代码的痛苦经历:
compare = lambda s, p: re.match(p, s)
然后我用compare in
[x for x in data if compare(patternPhrases, x[columnIndex])]
其中patternPhrases应该是一个包含正则表达式字符串的变量,x[columnIndex]是一个包含字符串的变量。
我有麻烦,patternPhrases不匹配一些预期的字符串!
但是如果我使用re.compile形式:
compare = lambda s, p: p.match(s)
然后在
[x for x in data if compare(patternPhrases, x[columnIndex])]
Python会抱怨“字符串没有匹配属性”,因为在compare中通过位置参数映射,x[columnIndex]被用作正则表达式!其实我的意思是
compare = lambda p, s: p.match(s)
在我的例子中,使用re.compile更明确地表达了正则表达式的目的,当它的值对肉眼隐藏时,因此我可以从Python运行时检查中获得更多帮助。
因此,我这一课的寓意是,当正则表达式不仅仅是字面字符串时,那么我应该使用re.compile让Python帮助我断言我的假设。
一般来说,我发现在编译模式时使用标志比内联使用标志更容易(至少更容易记住如何使用),比如re.I。
>>> foo_pat = re.compile('foo',re.I)
>>> foo_pat.findall('some string FoO bar')
['FoO']
vs
>>> re.findall('(?i)foo','some string FoO bar')
['FoO']
我真的很尊重上面所有的答案。在我看来 是的!当然,使用re.compile而不是一次又一次地编译正则表达式是值得的。
使用re.compile可以使代码更加动态,因为您可以调用已经编译好的正则表达式,而不是一次又一次地编译。这对你有好处:
处理器的努力 时间复杂度。 使正则表达式通用。(可以在findall, search, match中使用) 并使您的程序看起来很酷。
例子:
example_string = "The room number of her room is 26A7B."
find_alpha_numeric_string = re.compile(r"\b\w+\b")
在Findall中使用
find_alpha_numeric_string.findall(example_string)
在搜索中使用
find_alpha_numeric_string.search(example_string)
类似地,您可以将它用于:Match和Substitute
尽管这两种方法在速度方面是可以比较的,但是您应该知道,如果您正在处理数百万次迭代,那么仍然存在一些可以忽略不计的时间差。
以下速度测试:
import re
import time
SIZE = 100_000_000
start = time.time()
foo = re.compile('foo')
[foo.search('bar') for _ in range(SIZE)]
print('compiled: ', time.time() - start)
start = time.time()
[re.search('foo', 'bar') for _ in range(SIZE)]
print('uncompiled:', time.time() - start)
给出了以下结果:
compiled: 14.647532224655151
uncompiled: 61.483458042144775
编译后的方法在我的PC上(使用Python 3.7.0)始终快大约4倍。
如文档中所述:
如果在循环中访问正则表达式,预编译它将节省一些函数调用。在循环之外,由于内部缓存,没有太大区别。
根据Python文档:
序列
prog = re.compile(pattern)
result = prog.match(string)
等于
result = re.match(pattern, string)
但是,当表达式将在一个程序中多次使用时,使用re.compile()并保存生成的正则表达式对象以供重用会更有效。
所以我的结论是,如果你要为许多不同的文本匹配相同的模式,你最好预编译它。