2013-04-17 57 views
0

我寫了一個簡單的測試應用程序來檢查使用正則表達式滿足我的需求的可能性。我需要找到並用一些唯一的字符串替換所提供的文本文件中的所有重複標籤。例如,如果某些文本會在輸入文件中找到,那麼應該用{1}替換它的所有出現,依此類推。正則表現隨着時間的推移而退化

爲此我已創建下面的代碼片段:

static void Main(string[] args) 
    { 
     StringBuilder xml = new StringBuilder(File.ReadAllText(@"C:\Integration\Item-26 - Copy.xml")); 

     Regex r = new Regex(
      @"(?<exp>\<(?<tag>[^\<\>\s]+)[^\<\>]*\>[^\<\>]+\<\/\k<tag>\>).*\k<exp>", 
      RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.CultureInvariant); 

     List<string> values = new List<string>(); 

     MatchCollection matches = r.Matches(xml.ToString()); 

     Stopwatch stopwatch = new Stopwatch(); 
     stopwatch.Start(); 

     while (matches.Count > 0) 
     { 
      foreach (Match m in matches) 
      { 
       string matchValue = m.Groups["exp"].Value; 
       values.Add(matchValue); 
       xml.Replace(matchValue, string.Concat("{" + (values.Count - 1) + "}")); 
      } 

      Console.WriteLine("Analyzed " + matches.Count + " matches, total replacements = " + values.Count); 

      matches = r.Matches(xml.ToString()); 
     } 

     stopwatch.Stop(); 

     Console.WriteLine("=============== " + stopwatch.Elapsed.TotalSeconds); 
     Console.ReadLine(); 
    } 

的問題是,如果我有一個大的文件作爲輸入(> 1MB),然後每次調用查找匹配比以前需要更長的時間。在開始時,需要0.3秒來調用matches.Count。經過100次迭代後,需要1分鐘以上。

我已經檢查了測試應用程序的內存使用情況 - 它幾乎不消耗任何實際的增長。

這是什麼原因造成的?我該如何獲得穩定的性能? 在此先感謝。

+0

先刪除編譯後的屬性。它可能只是解決你的神祕感。 – Serge

+0

已經試過這個(以及其他選項的變化) - 它沒有幫助。 – Amid

+0

嗯......你用正則表達式解析你的xml數據嗎?我的意思是在你的代碼中的這一行:「'MatchCollection matches = r.Matches(xml.ToString());'' –

回答

1

這是我認爲的問題是。你的正則表達式是:

@"(?<exp>\<(?<tag>[^\<\>\s]+)[^\<\>]*\>[^\<\>]+\<\/\k<tag>\>).*\k<exp>" 

所以,你正在尋找的東西,如:

<tag>stuff</tag>lots of stuff here<tag>stuff</tag> 

在第一次迭代中,正則表達式很快失敗,因爲內部的標籤就被替換,因爲標籤是併攏。但隨着更多的內部標籤被替換,標籤之間的空間增加。不久你有:

<tag>stuff</tag>hundreds of kilobytes<tag2>other stuff</tag2><tag>stuff</tag> 

而回溯開始殺死你。

我懷疑你可以用[^\<]*代替.*(或我之前建議的.*?)來解決這個問題。因爲你知道當你發現一個<,那麼你要麼找到了一場比賽,要麼是一個明確的失敗。

+0

我認爲你是對的。感謝您的幫助。 – Amid

相關問題