为什么要有re.match()?

spi*_*der 6 python regex

我知道这个话题已经讨论过多次 在这里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)

Cas*_*yte 4

如您所知,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取决于字符串大小。