簡體   English   中英

在Python中編譯正則表達式

[英]Compiling Regular Expressions in Python

我正在研究Doug Hellman的“示例中的Python標准庫”並且遇到了這個:

“1.3.2編譯表達式包括用於將正則表達式作為文本字符串處理的模塊級函數,但編譯程序經常使用的表達式更有效。”

我不能按照他的解釋為什么會這樣。 他說“模塊級函數維護編譯表達式的緩存”,並且由於“緩存大小”有限,“使用編譯表達式直接避免了緩存查找開銷。”

如果有人可以解釋或指導我解釋一下,我可以更好地理解為什么編譯程序經常使用的正則表達式更有效,以及這個過程實際如何工作,我將非常感激。

嗯。 這很奇怪。 到目前為止,我的知識( 從這個問題獲得了其他來源)提出了我的初步答案:


第一個答案

Python緩存您使用的最后100個正則表達式,因此即使您沒有顯式編譯它們,也不必在每次使用時重新編譯它們。

但是,有兩個缺點:當達到100個正則表達式的限制時,整個緩存都會被破壞,因此如果連續使用101個不同的正則表達式,每次都會重新編譯每個正則表達式。 嗯,這不太可能,但仍然。

其次,為了找出是否已經編譯了正則表達式,解釋器需要每次都在緩存中查找正則表達式,這需要花費一些額外的時間(但由於字典查找速度非常快)。

因此,如果您顯式編譯正則表達式,則可以避免這個額外的查找步驟。


更新

我剛做了一些測試(Python 3.3):

>>> import timeit
>>> timeit.timeit(setup="import re", stmt='''r=re.compile(r"\w+")\nfor i in range(10):\n r.search("  jkdhf  ")''')
18.547793477671938
>>> timeit.timeit(setup="import re", stmt='''for i in range(10):\n re.search(r"\w+","  jkdhf  ")''')
106.47892003890324

所以似乎沒有進行緩存。 也許這是timeit.timeit()運行的特殊條件的怪癖?

另一方面,在Python 2.7中,差異並不明顯:

>>> import timeit
>>> timeit.timeit(setup="import re", stmt='''r=re.compile(r"\w+")\nfor i in range(10):\n r.search("  jkdhf  ")''')
7.248294908492429
>>> timeit.timeit(setup="import re", stmt='''for i in range(10):\n re.search(r"\w+","  jkdhf  ")''')
18.26713670282241

我相信他想說的是你不應該在你的循環中編譯你的正則表達式,而是在它之外。 然后,您可以在循環內運行已編譯的代碼。

代替:

while true: 
    result = re.match('A', str)

你應該把:

regex = re.compile('A')
while true:
    result = regex.match(str)

基本上 re.match(pattern, str)結合了編譯和匹配步驟。 在循環內編譯相同的模式是低效的,因此應該在循環之外提升。

請參閱Tim對正確推理的回答。

聽起來像是作者只是說編譯正則表達式更有效並保存,而不是指望它仍然保存在模塊的有限大小的內部緩存中的先前編譯版本。 這可能是因為編譯它們所需的工作量加上必須首先發生的額外緩存查找開銷大於客戶端只是簡單地存儲它們本身。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM