防止在正则表达式上回溯以查找非注释行(不是以缩进的“#”开头)

Prevent backtracking on regex to find non-comment lines (not starting with indented '#')

我想在缩进代码中搜索不以井号 (#) 开头的行。

目前,我正在使用正则表达式 ^\s*([^\s#].*) 并启用了多行选项。

我的问题是,在非注释行上,它工作得很好。

在注释行上,由于 \s* 从注释符号到行的开头,正则表达式引擎执行回溯,有时会导致 40 或 50 个回溯步骤。

正则表达式在 python 代码上完美运行。只是由于引擎造成的回溯,效率不是很高。

知道如何避免吗?


奖励:很有趣的是,正则表达式引擎无法识别它正在 \s* 中一个接一个地搜索 [^\s] 并导致如此多的回溯。使重新引擎如此工作的挑战是什么?

奖励 2:仅使用 stdlib re 模块。因为我不能添加第 3 方。 (我在技术上使用 sublime text 进行搜索,但想知道通常如何在 Python 中进行搜索)

使用atomic feature of lookarounds避免回溯:

^(?=(\s*))([^#].*)
    ^^^^^  ^

这种用法在@vks 漂亮地提出的负前瞻中得到了简化。

或使用 regex 模块时的所有格量词:

^\s*+([^#].*)

甚至原子团:

^(?>\s*)([^#].*)

自从在 PCRE 上以来,Sublime Text 支持所有这三个。

对于奖金部分,不,这并不好笑。如果你更敏锐地观察它,你会发现它不是 [^\s] ,它实际上等于 \S 但它有点不同: [^\s#] 对于引擎来说意味着它有两个在每一步寻找不同的路径,因此它回溯到一个。

你可以简单地说

^(?!\s*#).*

This takes just 6 steps in comparison to 33 steps taken by yours.