在没有灾难性回溯的情况下重写正则表达式?

Rewrite a Regular Expression without Catastrophic Backtracking?

我想知道是否有人可以检查这个正则表达式并在没有灾难性回溯的情况下重写它?我的 SonarQube 似乎不高兴。 ;)

String NEGATIVE = "(.*?[^0-9]+?)-([0-9.]+?.*?)";

根据 Java 代码,它正在尝试使用此表达式来帮助查找负数符号并将其替换为波浪字符。

// Replace any negative number signs as they will
// be confused with the subtraction operator.
expression = expression.replaceAll(NEGATIVE, "~").replaceFirst("^-", "~");

谢谢。

这将匹配基本表达式中数字前的所有负号。执行,然后用 ~.

替换整个匹配

您没有post您的输入集,因此可能还有其他情况需要编码。

(?<=[-+*\/0-9 ]|^)-(?=[\d]+)

这里有一些替换的例子 https://regex101.com/r/3H30tU/1https://regex101.com/r/3H30tU/1

在patten (.*?[^0-9]+?)-([0-9.]+?.*?)中,末尾的非贪婪部分.*?可以省略,因为它不会匹配任何字符。

这部分[0-9.]+?只会匹配1个字符,因为量词是非贪婪的,所以量词可以省略(因为下面的.*?不匹配任何字符)

您可以在断言中仅使用一个字符进行环视:

(?<!\d)-(?=\d)
  • (?<!\d) 否定向后看,断言不是当前位置左边的数字
  • - 匹配连字符
  • (?=\d) 正面前瞻,直接在当前位置的右侧断言一个数字

Regex demo