【问题标题】:Regex pattern matching takes a long time for strings with length more than 30 chars对于长度超过 30 个字符的字符串,正则表达式模式匹配需要很长时间
【发布时间】:2018-04-07 17:47:24
【问题描述】:

在 Spring @Pattern 使用正则表达式 ^([a-zA-Z0-9-_]+ ?)+$ 进行注释, 它匹配任何长度的有效字符串,但以下字符串需要超过 4800 毫秒

Test regex -121-test valid future_4 %$^&. 

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

future_4%$^& , $$%%

请解释为什么会发生这种情况以及相同的解决方案? 提前致谢。

【问题讨论】:

  • 问题是什么?
  • 感谢您分享您的发现。如果您需要帮助,您需要提出具体问题
  • 我认为问题是在标题中提出的,而不是在正文中,看起来 OP 想知道如何实现正则表达式匹配的超时或其他内容
  • 这是一种灾难性回溯(量词内的量词)的模式。

标签: java regex spring


【解决方案1】:

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

也就是说,当单词/连字符字符后没有空格时,您的模式会变成 ^[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_-]+ - 1 个或多个字母、数字、_-
  • (?: [a-zA-Z0-9_-]+)* - 零个或多个序列
    • - 空格
    • [a-zA-Z0-9_-]+ - 1 个或多个字母、数字、_-
  • $ - 字符串结束。

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

【讨论】:

    猜你喜欢
    • 2015-12-23
    • 2015-09-19
    • 2015-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-25
    • 2019-01-04
    相关资源
    最近更新 更多