我在Perl工作,它使用回溯正则表达式引擎。
我需要匹配以空格分隔的标记的字符串(我正在解析汇编程序,以防有人想知道)。我目前正在使用像
这样的正则表达式s/(\.text\n\s*\.align .(?:,0x90)?\n)\.globl\s+.*_?__stg_split_marker.*\n/$1/m
这样做,但我担心过度回溯。
我该如何防止这种情况?
答案 0 :(得分:1)
一般方法是针对任何可能要进行回溯的子表达式,使用(?>...)
包围子表达式。
例如,\s+
将为(?>\s+)
。
答案 1 :(得分:0)
根据我的经验,很多人都试图在not required的地方使用正则表达式,很多人都试图避免它们where they're the best solution。所以我必须始终问 - 你想做什么?
对我来说,你要试图拆分一些代码。或许更容易扭转它,并且总是把它拉开然后将它作为制作过程的一部分组合起来?对于这种类型的东西,我经常会使用模板让我以正确的方式构建代码,并在此构建单元的特定代码中进行插值。然后我完全避免了正则表达式问题,这意味着我也可以避免开发人员做了一些我从未想到的事情。“/ p>
答案 2 :(得分:0)
老实说,该代码应该很少回溯。整个事情由.text
锚定,其他可能发生回溯的地方将很快中止。不过,您可以尝试进行优化。
\K
删除了捕获(减慢速度)的需要。鉴于我上面所说的,这可能是提供最大利益的优化。 \s*
替换为\s*+
又名(?>\s*)
(防止回溯,这是安全的,因为下一个字符不能是空格)。.*
替换为.*+
又称(?>.*)
(防止回溯,这是安全的,因为下一个字符不能是非换行符。)(?:,0x90)?
替换为(?:,0x90)?+
(防止回溯,这是安全的,因为下一个字符不能是逗号)。\s+.*_?
替换为更简单但等效的\s.*
。
s/
\.text \n
\s*+
\.align [ ] .(?:,0x90)?+ \n
\K
\.globl \s .* __stg_split_marker .*+ \n
//xm