我知道这个话题已经讨论过多次 次在这里StackOverflow上,但我在寻找一个更好的答案.
虽然我很欣赏的差异,我是不是真的能找到一个明确的解释,为什么在re
在Python模块同时提供match()
和search()
.search()
如果我^
在单线模式下,/A
在多线模式下,我不能得到相同的行为吗?我错过了什么吗?
我试图理解查看_sre.c代码的实现,我理解search(sre_search()
)实际上是实现了在要搜索的字符串中移动指针,并sre_match()
在其上应用,直到找到匹配.
所以我想使用re.match()
可能会比使用相应的正则表达式(使用^
或者/A
)略快一些re.search()
.这是什么原因?
我也研究了python-dev ML档案,但无济于事.
>>> string="""first line
... second line"""
>>> print re.match('first', string, re.MULTILINE)
<_sre.SRE_Match object at 0x1072ae7e8>
>>> print re.match('second', string, re.MULTILINE)
None
>>> print re.search('\Afirst', string, re.MULTILINE)
<_sre.SRE_Match object at 0x1072ae7e8>
>>> print re.search('\Asecond', string, re.MULTILINE)
None
Run Code Online (Sandbox Code Playgroud)
如您所知,re.match
将仅在字符串的开头测试模式,并将re.search
测试所有字符串,直到找到匹配项。
那么,re.match('toto', s)
和之间有区别re.search('^toto', s)
吗?
我们来做个小测试:
#!/usr/bin/python
import time
import re
p1 = re.compile(r'toto')
p2 = re.compile(r'^toto')
ssize = 1000
s1 = 'toto abcdefghijklmnopqrstuvwxyz012356789'*ssize
s2 = 'titi abcdefghijklmnopqrstuvwxyz012356789'*ssize
nb = 1000
i = 0
t0 = time.time()
while i < nb:
p1.match(s1)
i += 1
t1 = time.time()
i = 0
t2 = time.time()
while i < nb:
p2.search(s1)
i += 1
t3 = time.time()
print "\nsucceed\nmatch:"
print (t1-t0)
print "search:"
print (t3-t2)
i = 0
t0 = time.time()
while i < nb:
p1.match(s2)
i += 1
t1 = time.time()
i = 0
t2 = time.time()
while i < nb:
p2.search(s2)
i += 1
t3 = time.time()
print "\nfail\nmatch:"
print (t1-t0)
print "search:"
print (t3-t2)
Run Code Online (Sandbox Code Playgroud)
这两种方式分别用不匹配的字符串和匹配的字符串进行测试。
结果:
succeed
match:
0.000469207763672
search:
0.000494003295898
fail
match:
0.000430107116699
search:
0.46605682373
Run Code Online (Sandbox Code Playgroud)
从这些结果我们可以得出什么结论:
1)当模式成功时,性能相似
2)当模式失败时,性能完全不同。这是最重要的一点,因为,这意味着re.search
即使模式在re.match
立即停止时被锚定,也会继续测试字符串的每个位置。
如果增加失败测试字符串的大小,您会发现这re.match
不会花费更多时间,而是re.search
取决于字符串大小。