【问题标题】:Regex.IsMatch is causing catastrophic backtrackingRegex.IsMatch 导致灾难性的回溯
【发布时间】:2020-04-12 08:01:25
【问题描述】:

我知道有很多类似的问题,但这是我的正则表达式特有的。 我正在尝试查看字符串中是否包含任何 html。

Regex tagRegex = new Regex(@"<\s*([^ >]+)[^>]*>.*?<\s*/\s*\1\s*>")
if(tagRegex.IsMatch(body))
{
  *do something*
}

但由于灾难性的回溯,它在 IsMatch 部分失败。谁能告诉我正则表达式有什么问题?

谢谢

【问题讨论】:

  • 是的,这个片段( [^ &gt;]+ ) 吹过&lt;/junk&gt;&lt;tag\nsome junk/&gt; 之类的标签,然后继续尝试将\1 放入其中。这是一个缓慢的过程。
  • 您是要匹配 不可见的内容 还是只是打开/关闭标签?
  • 我建议将其用于不可见内容&lt;(?:(script|style|object|embed|applet|noframes|noscript|noembed)(?:\s+(?&gt;"[\S\s]*?"|'[\S\s]*?'|(?:(?!/&gt;)[^&gt;])?)+)?\s*&gt;)[\S\s]*?&lt;/\1\s*&gt;
  • 你可以使用这个&lt;(?:([\w:]+)(?:\s+(?&gt;"[\S\s]*?"|'[\S\s]*?'|(?:(?!/&gt;)[^&gt;])?)+)?\s*&gt;)[\S\s]*?&lt;/\1\s*&gt;,但它会像&lt;html&gt; to &lt;/html&gt;一样匹配我建议只使用下一个标签正则表达式来查看它是否有html。见下。

标签: c# regex


【解决方案1】:

在正则表达式中使用* 是大多数回溯发生的地方。这就像在说,“那里可能有东西,但可能没有……所以继续寻找”。这种优柔寡断导致回溯寻找其他替代方案......

你的模式的问题是它试图做所有事情,但由于回溯而最终什么都不做。需要通过指定要查找的特定事物来保持模式紧密,并且如果有的话,只使用*

将您的模式缩短为一条规则,然后向其中添加更多规则。它成为完全合规性和速度之间的权衡;你需要打那个电话。


有关详细信息,请参阅 MS Docs Take Charge of Backtracking

【讨论】:

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