【问题标题】:RegularExpressions.Match hangs in infinite loopRegularExpressions.Match 在无限循环中挂起
【发布时间】:2012-01-18 13:44:00
【问题描述】:

此代码在无限循环中挂起。

任何想法为什么会这样?这是.NET中的错误吗?我能做点什么吗?

Dim urlRegex As New
Regex("((?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|ftp[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'"".,<>?«»“”‘’]))",
RegexOptions.IgnoreCase)

Dim match As System.Text.RegularExpressions.Match = urlRegex.Match("<a ""javascript:window.Add(location.href,document.title)"">")

【问题讨论】:

  • 你能在它周围抛出一个 try/catch 看看是否有任何异常吗?
  • 在 Try/Catch 块中执行时没有异常。
  • Jiri,它不会挂起,只是需要很长的时间。所以这不是错误,您应该编辑您的问题以询问优化正则表达式的方法。
  • 元骑士:你确定吗?它运行了一夜并没有完成。
  • 您的问题几乎肯定与回溯有关。在此处阅读 MSDN 文章msdn.microsoft.com/en-us/library/gg578045.aspx#Backtracking。如果这有意义,请尝试实施它。如果它没有(即使它确实如此),为了未来的编码人员,包括你未来的自己,将你的正则表达式重写为更简单的东西,可能是两个或三个正则表达式。找到一个可以定位的较大模式,提取子字符串,然后解析较小的部分。 @Meta-Knight 是对的,在我的机器上完成了大约 5 分钟。

标签: .net regex vb.net


【解决方案1】:

正如其他人所提到的,这是由于过度回溯。关于这个主题的一篇好文章可以在这里阅读:Catastrophic Backtracking

您的选择是:

  1. 更好地定义您的模式,不要使用可能导致灾难性回溯的嵌套量词。这需要你更好地定义你的问题。建立一个可能的输入列表,也许会出现更好的模式。通过指定允许的内容和不允许的内容,您的模式似乎试图做太多事情。有时可以通过做一个或另一个来简化模式。你想匹配什么?

  2. 使用 .NET 4.5 的新 Regex 超时功能(一旦正式发布)。虽然这不是解决您的问题的直接方法,但它确实有助于防止因模式不佳而导致匹配挂起。我在这里介绍过:How do I timeout Regex operations to prevent hanging in .NET 4.5?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-17
    • 2019-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多