「因此,更新後的問題是,爲什麼現在搜索出表現是否匹配?」
在一個字符串使用,而不是一個正則表達式這種特殊的情況下,確實re.search
比re.match
默認CPython的實現(我還沒有在Python的其他化身測試這一點)稍快。
>>> print timeit.timeit(stmt="r.match(s)",
... setup="import re; s = 'helloab'*100000; r = re.compile('hello')",
... number = 10000000)
3.29107403755
>>> print timeit.timeit(stmt="r.search(s)",
... setup="import re; s = 'helloab'*100000; r = re.compile('hello')",
... number = 10000000)
2.39184308052
展望C code behind those modules,它出現在搜索代碼有一個內置的優化to quickly match patterns prefixed with a string lateral。在上面的示例中,整個模式是一個沒有正則表達式模式的文字字符串,所以這個優化的例程用於匹配整個模式。
通知一旦我們介紹的正則表達式的符號和,作爲文字串前綴變短的性能如何降低:
>>> print timeit.timeit(stmt="r.search(s)",
... setup="import re; s = 'helloab'*100000; r = re.compile('hell.')",
... number = 10000000)
3.20765399933
>>>
>>> print timeit.timeit(stmt="r.search(s)",
... setup="import re; s = 'helloab'*100000; r = re.compile('hel.o')",
... number = 10000000)
3.31512498856
>>> print timeit.timeit(stmt="r.search(s)",
... setup="import re; s = 'helloab'*100000; r = re.compile('he.lo')",
... number = 10000000)
3.31983995438
>>> print timeit.timeit(stmt="r.search(s)",
... setup="import re; s = 'helloab'*100000; r = re.compile('h.llo')",
... number = 10000000)
3.39261603355
對於包含正則表達式模式的圖案的部分,SRE_MATCH被用於確定匹配。這與re.match
背後的代碼基本相同。
如果模式以正則表達式模式而非文字字符串開頭,請注意結果如何接近(re.match
稍快)。
>>> print timeit.timeit(stmt="r.match(s)",
... setup="import re; s = 'helloab'*100000; r = re.compile('.ello')",
... number = 10000000)
3.22782492638
>>> print timeit.timeit(stmt="r.search(s)",
... setup="import re; s = 'helloab'*100000; r = re.compile('.ello')",
... number = 10000000)
3.31773591042
換句話說,忽略這一事實search
和match
具有不同的目的,re.search
比re.match
更快僅當模式是文字串。
當然,如果您使用的是文字字符串,您可能更願意使用字符串操作。
>>> # Detecting exact matches
>>> print timeit.timeit(stmt="s == r",
... setup="s = 'helloab'*100000; r = 'hello'",
... number = 10000000)
0.339027881622
>>> # Determine if string contains another string
>>> print timeit.timeit(stmt="s in r",
... setup="s = 'helloab'*100000; r = 'hello'",
... number = 10000000)
0.479326963425
>>> # detecting prefix
>>> print timeit.timeit(stmt="s.startswith(r)",
... setup="s = 'helloab'*100000; r = 'hello'",
... number = 10000000)
1.49393510818
>>> print timeit.timeit(stmt="s[:len(r)] == r",
... setup="s = 'helloab'*100000; r = 'hello'",
... number = 10000000)
1.21005606651
你真的應該在'setup'參數中爲'timeit'構建測試字符串和正則表達式對象,這樣你只能測量匹配/搜索本身。並且做10次以上的迭代。 – interjay
@interjay:增加到10000。試過'號碼= 100000',但在我的上網本上花費了太多時間。 – RanRag
...但你沒有做我說的其他事情,所以你沒有測量任何重要的問題(大部分時間都花在構建字符串上)。 – interjay