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

问题描述 投票:6回答:2

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

目前,我正在使用带有多行选项的正则表达式^\s*([^\s#].*)

我的问题是在非注释行上它完美地工作。

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

正则表达式完全适用于python代码。由于发动机引起的回溯,它效率不高。

关于如何避免它的任何想法?


额外奖励:有趣的是,正则表达式引擎无法识别它在[^\s]中逐个搜索\s*这一事实并导致这一数量的回溯。使重新发动机工作的挑战是什么?

奖励2:仅使用stdlib re模块。因为我无法添加第三方。 (我在技术上使用sublime文本搜索,但想知道如何在Python中一般地使用它)

python regex python-3.x backtracking negative-lookahead
2个回答
5
投票

使用atomic feature of lookarounds来避免回溯:

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

这种用法在@vks精美提出的负向前瞻中得到了简化。

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

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

甚至原子团:

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

Sublime Text支持所有三个,因为它们在PCRE上。

对于奖金部分,不,这不好笑。如果你更加老鹰眼,你会发现它不是[^\s],它实际上与\S相同,但它有点不同:[^\s#]对于引擎意味着它在每一步都有两条不同的路径来寻找它所以它回溯到到达一个。


4
投票

你可以简单地说

^(?!\s*#).*

This采取的33步相比,yours只需要6步。

© www.soinside.com 2019 - 2024. All rights reserved.