对于长度超过30个字符的字符串,正则表达式模式匹配需要很长时间

时间:2017-10-26 11:07:56

标签: java regex spring

在Spring @Pattern注释中使用正则表达式^([a-zA-Z0-9-_]+ ?)+$, 它匹配任何长度的有效字符串,但下面的字符串

需要超过4800毫秒
Test regex -121-test valid future_4 %$^&. 

长度较小的无效模式也可正常工作,例如:

future_4%$^& , $$%%

请解释为什么会发生这种情况并解决相同问题? 提前谢谢。

1 个答案:

答案 0 :(得分:6)

始终确保您的模式以线性方式编写,也就是说,相邻的子模式与前面的模式不匹配相同的字符。

那就是说,你的模式,当一个单词/连字符后面没有空格时,会变成类似^[a-zA-Z0-9-_]+[a-zA-Z0-9-_]+[a-zA-Z0-9-_]+[a-zA-Z0-9-_]+...$的东西,并且涉及太多的回溯(我省略了一个捕获组,但在你的模式中,第1组价值也会不断重写,这也妨碍了匹配)。

使用

^[a-zA-Z0-9_-]+(?: [a-zA-Z0-9_-]+)*$

<强>详情

  • ^ - 字符串开头
  • [a-zA-Z0-9_-]+ - 一个或多个字母,数字,_-
  • (?: [a-zA-Z0-9_-]+)* - 零个或多个序列
    • - space
    • [a-zA-Z0-9_-]+ - 一个或多个字母,数字,_-
  • $ - 字符串结束。

虽然your regex会导致灾难性的回溯,mine会优雅地失败。