簡體   English   中英

可憐的Python'表現'的情況

[英]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.

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