【问题标题】:Prevent catastrophic backtracking in this regex在这个正则表达式中防止灾难性的回溯
【发布时间】:2019-07-05 07:06:30
【问题描述】:

(\W*\d+)*(?=\W|$)

我遇到了这个正则表达式的问题,导致系统在搜索某个词时崩溃。

我正试图找到在不改变其逻辑的情况下消除灾难性回溯的方法,但到目前为止我一无所获。

任期: 0000000000000000000000000000Abc

你可以在这里测试一下,看看超时时间:

【问题讨论】:

  • 您搜索什么文本?图案要求是什么?请提供一些例子。
  • 嗯,可靠地防止灾难性回溯的唯一方法是远离某些容易出现的正则表达式模式。没有什么神奇的方法可以让模式在不改变它的情况下遭受灾难性回溯问题(如果有这样的方法,灾难性回溯问题在很多很多年前就已经在正则表达式引擎中解决了,你不觉得吗? )
  • 至少删除+(\W*\d)*(?!\w)\W 匹配任何非单词数字,这将启用“线性”匹配。
  • 我认为这就是我想要的。删除“+”将防止灾难性的回溯。

标签: c# regex


【解决方案1】:

您需要在\d 之后删除+,否则,在承认不匹配之前,正则表达式引擎会花费很长时间来测试匹配不匹配字符串的所有可能方法。

使用

(?:\W*\d)*(?!\w)

(?:\W*\d)*\b

\W 匹配任何非单词字符(因此,没有数字),当 d 匹配时,\W* 将消耗 0 个或更多非单词字符,从而实现“线性”匹配方式,当随后的子模式与前面的子模式不匹配相同的文本。

(?!\w) 前瞻工作比交替组 (?:\W|$) 快一点,因为它所要做的就是检查下一个字符是否为单词字符,如果是,则匹配失败。实际上,在这种情况下,在\d之后,(?!\w)等于\b,一个词的边界,所以在这个位置使用它是最好的构造。

请参阅regex demo

【讨论】:

    猜你喜欢
    • 2017-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多