[英]Case of poor Python 're' performance
我在lua中用於自動完成的 Sublime包使用了Python的're'模塊,但是一個正則表達式導致了重大的減速。 這是一個最小的例子:
import re
rx = re.compile(r"\bfunction(?:\s+[a-zA-Z0-9._]*)?\(((?:[a-zA-Z_][a-zA-Z0-9_]*|\.\.\.|,\s*)*)\)")
rx.match('function f(aaaaaaa, bbbbbbbb, cccccccc, ddddddd eeeeee)') # Very slow
rx.match('function f(aaaaaaa, bbbbbbbb, cccccccc, ddddddd, eeeeee)') # Adding a comma between the last function arguments in the string fixes it.
我正在使用正則表達式調試,但這看起來很有意義 ,盡管它超出了我的想象。
有誰知道我可以使用的等效模式,但哪個具有良好的性能?
謝謝!
問題是該模式包含*
-quantified *
量詞: (?:[a-zA-Z_][a-zA-Z0-9_]*|\\.\\.\\.|,\\s*)*
。 必須避免使用這些嵌套量詞。 如果您無法將備選方案重新安排到后續(可選)組中,則占有量詞或原子組通常會有所幫助。
Python的re
不支持占有欲量詞,也不支持原子團。
但是,您可以使用具有模擬原子組的版本:
\bfunction(?:\s+[a-zA-Z0-9._]*)?\(((?:(?=([a-zA-Z_][a-zA-Z0-9_]*))\2|\.\.\.|,\s*)*)\)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
將[a-zA-Z_][a-zA-Z0-9_]*
子圖案放入捕獲組中,該組采用正向后觀。 (?=([a-zA-Z_][a-zA-Z0-9_]*))\\2
與[a-zA-Z_][a-zA-Z0-9_]*
幾乎相同(因為它匹配相同的東西) [a-zA-Z_][a-zA-Z0-9_]*
但它使子模式成為原子(因此,在其他類型中它看起來像[a-zA-Z_][a-zA-Z0-9_]*+
或(?>[a-zA-Z_][a-zA-Z0-9_]*+)
)。 \\2
反向引用的“原子”性質不會讓回溯超出[a-zA-Z_][a-zA-Z0-9_]*
。
請參閱正則表達式演示 。
也許,你想要re.search
因為你的模式以\\b
開頭。 請注意, re.match
只能在字符串的開頭找到匹配項(=它錨定在字符串的開頭)。
主要問題來自嵌套量詞(?:[a-zA-Z_][a-zA-Z0-9_]*|\\.\\.\\.|,\\s*)*
可能會導致災難性的回溯以下子模式失敗。
如果您展開*此子模式,則可以避免此問題。 我使用了詳細模式使其更具可讀性:
re.compile(r'''\bfunction\b \s*[a-zA-Z0-9._]*
\(
(
(?:
(?:[a-zA-Z_][a-zA-Z0-9_]*|\.\.\.)
(?: ,\s* (?:[a-zA-Z_][a-zA-Z0-9_]*|\.\.\.) )*
)?
)
\)''', re.VERBOSE)
(*) :基本上是將(a*|b)*
改為a*(ba*)*
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.