正则表达式因某些记录而陷入困境

时间:2015-06-04 05:49:09

标签: c# regex visual-studio-2010

有时候Regex会遇到一些值,尽管它会为大多数文档提供结果。

我正在谈论当它被卡住时的场景。

  1- collection = Regex.Matches(document, pattern,RegexOptions.Compiled);
  2-  if (collection.Count > 0) //This Line
            {

我调试了解决方案,希望在监视窗口中看到集合的值。我看到了大多数属性的结果。

Function evaluation disabled because a previous function evaluation timed out. You must continue execution to reenable function evaluation.

后来它被困在第二线。

我可以看到正则表达式存在一些问题,因此它进入了循环。

问题: 我没有得到任何例外。我有任何办法可以在超时后获得异常,所以我的工具可以继续进行其余的工作。

 Regex:      @"""price"">(.|\r|\n)*?pound;(?<data>.*?)</span>"

 Part of Document : </span><span>1</span></a></li>\n\t\t\t\t<li>\n\t\t\t\t\t<span class=\"icon icon_floorplan touchsearch-icon touchsearch-icon-floorplan none\">Floorplans: </span><span>0</span></li>\n\t\t\t\t</ul>\n\t\t</div>\n    </div>\n\t</div>\n<div class=\"details clearfix\">\n\t\t<div class=\"price-new touchsearch-summary-list-item-price\">\r\n\t<a href=\"/commercial-property-for-sale/property-47109002.html\">POA</a></div>\r\n<p class=\"price\">\r\n\t\t\t<span>POA</span>\r\n\t\t\t\t</p>\r\n\t<h2 class=\"address bedrooms\">\r\n\t<a id=\"standardPropertySummary47109002\"

1 个答案:

答案 0 :(得分:5)

如何在Regex搜索过长时间内获得异常?

请阅读以下有关在正则表达式搜索中设置超时的信息。

MSDN: Regex.MatchTimeout Property

  

MatchTimeout属性定义Regex实例在操作超时之前执行单个匹配操作的近似最大时间间隔。 正则表达式引擎在超时间隔结束后的下一次计时检查期间抛出RegexMatchTimeoutException异常。这可以防止正则表达式引擎处理需要过多回溯的输入字符串。有关更多信息,请参阅.NET Framework中正则表达式的正向跟踪和正则表达式的最佳实践。

    public static void Main()
    {
        AppDomain domain = AppDomain.CurrentDomain;
        // Set a timeout interval of 2 seconds.
        domain.SetData("REGEX_DEFAULT_MATCH_TIMEOUT", TimeSpan.FromSeconds(2));
        Object timeout = domain.GetData("REGEX_DEFAULT_MATCH_TIMEOUT");
        Console.WriteLine("Default regex match timeout: {0}",
                            timeout == null ? "<null>" : timeout);

        Regex rgx = new Regex("[aeiouy]");
        Console.WriteLine("Regular expression pattern: {0}", rgx.ToString());
        Console.WriteLine("Timeout interval for this regex: {0} seconds",
                            rgx.MatchTimeout.TotalSeconds);
    }

    // The example displays the following output: 
    //       Default regex match timeout: 00:00:02 
    //       Regular expression pattern: [aeiouy] 
    //       Timeout interval for this regex: 2 seconds

为什么我的正则表达式会被卡住?

首先,尝试优化正则表达式,尽可能减少反向引用。 stribizhev评论了一个改进,所以对他赞不绝口。

  

另一件事:你的正则表达式实际上相当于“价格”&gt; [\ s \ S] ?磅;(?。?)(C#声明:@“”“价格”“&gt; ; [\ S \ S] 磅;(??)“)。它更好,因为回溯更少。 - stribizhev 6月4日9:23

其次,如果你遇到特定值的问题,你可以做的第一件事是追踪逻辑每次迭代(匹配),而不是抓住所有匹配 - 衬垫。

MSDN: Match.NextMatch Method

   public static void Main()
   {
      string pattern = "a*";
      string input = "abaabb";

      Match m = Regex.Match(input, pattern);
      while (m.Success) {
         Console.WriteLine("'{0}' found at index {1}.", 
                           m.Value, m.Index);
         m = m.NextMatch();
      }
   }

为了在不使用模式的情况下提高基准性能,通常将Regex对象放在静态类中并仅将它们实例化一次,并在实例化时将RegexOptions.Compiled添加到Regex(您已经完成)。 (Source

PS。能够故意导致总是可重现的超时(即无限循环)可能很方便。我将在下面分享。

string pattern = @"/[a-zA-Z0-9]+(\[([^]]*(]"")?)+])?$";
string input = "/aaa/bbb/ccc[@x='1' and @y=\"/aaa[name='z'] \"]";