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

时间:2018-02-04 17:46:08

标签: python regex python-3.x backtracking negative-lookahead

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

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

我的问题是,在非注释行上它完美运行。

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

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

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

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

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

2 个答案:

答案 0 :(得分:5)

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

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

这种用法在@vks精美提出的负面预测中得到了简化。

使用regex模块时

或占有量词:

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

甚至是原子团:

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

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

并且对于奖金部分,不,它不好笑。如果你对它更加敏锐,你会发现它不是[^\s],它实际上等于\S但它有点不同:[^\s#]对于引擎意味着它有两个每个步骤都要寻找不同的路径,以便回溯到达一个路径。

答案 1 :(得分:4)

你可以简单地说

^(?!\s*#).*
This采取的33个步骤相比,

yours只需要6个步骤。