防止在正则表达式上回溯以查找非注释行(不是以缩进的“#”开头)
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.
我想在缩进代码中搜索不以井号 (#) 开头的行。
目前,我正在使用正则表达式 ^\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.