2015-11-06 41 views
1

我正在使用Regex.Matches()解析來自大型文本文件的一串匹配。是否從C#的Regex.Matches返回的數組的順序保證按照文本的順序?

該函數是否有任何文檔保證Matches數組中的第一項將與文本中的第一個匹配對應,Matches數組中的第二個項與文本中的第二個匹配項相對應?

它似乎是基於Regex.Match的文檔嚴重隱含的,但我無法找到證明Regex.Matches將始終按文本中找到的順序返回匹配。

編輯

我發現一個整潔的網站,讓你去通過.NET源代碼。

所以從這裏開始:http://referencesource.microsoft.com/#System/regex/system/text/regularexpressions/Regex.cs,8d8851eac21ceb80

我們看到的比賽返回一個新MatchCollection,因爲它的使用,直到其推遲執行不執行任何操作。

http://referencesource.microsoft.com/#System/regex/system/text/regularexpressions/RegexMatchCollection.cs,682620f47b442b05,references

我們看到,對於MatchCollection主要數據結構是一個ArrayList,它不保證秩序。

_regex = regex; 
      _input = input; 
      _beginning = beginning; 
      _length = length; 
      _startat = startat; 
      _prevlen = -1; 
#if SILVERLIGHT 
      _matches = new List<Match>(); 
#else 
      _matches = new ArrayList(); 
#endif 
      _done = false; 

而且該GetMatch函數運行在文本中的順序正則表達式,將每一場比賽,因爲它沿到主數組列表去。

Match match; 

    do { 
     match = _regex.Run(false, _prevlen, _input, _beginning, _length, _startat); 

     if (!match.Success) { 
      _done = true; 
      return null; 
     } 

     _matches.Add(match); 

這對於我來說已經足夠了。

回答

2

雖然MSDN沒有具體說明它,但很明顯,匹配總是按順序排列的。 MSDN描述了MatchCollection對象如何延遲加載。由於正則表達式模式總是以線性方式處理(從左到右或從右到左),很難想象它們會以任何其他順序進行延遲加載。

例如,這裏是從this MSDN article的摘錄:

根據需要上的匹配通過匹配基礎的MatchCollection對象被填充。它相當於正則表達式引擎重複調用Regex.Match方法,並將每個匹配添加到集合中。當通過GetEnumerator方法訪問集合,或者使用foreach語句(在C#中)或For Each ...訪問集合時,將使用此技術。Next語句(在Visual Basic中)。

如果它與重複調用匹配(傳遞最後一個匹配的結束位置作爲下一個匹配的開始位置)相同,那麼很明顯這意味着它們將按順序排列。

當你結合起來,與該RegexOptions.RightToLeft選項的存在,它成爲even more clear

默認情況下,正則表達式引擎搜索從左到右。您可以使用RegexOptions.RightToLeft選項來反轉搜索方向。搜索自動從字符串的最後一個字符位置開始。對於包含起始位置參數(例如Regex.Match(String,Int32))的模式匹配方法,起始位置是開始搜索時最右側字符位置的索引。

即便如此,如果你不相信它,你必須保證順序,你可以通過Match.Index特性對它們進行排序:

var matches = Regex.Matches(input, pattern).OrderBy(x=>x.Index); 
+1

*總是在左到右線性方式處理* RegexOptions.RightToLeft'然後做了什麼? – PetSerAl

+0

@PetSerAl足夠:) –

+0

你的解決方案是聰明的,我可以自己訂購它。謝謝! – tt9

-1

不,沒有保證。它會按照它想要的順序返回它們,儘管它通常會按照它們被發現的順序返回它們。可能有些例子沒有。如果訂單絕對重要,則根據找到的地點對匹配進行排序。這就是說,我相信,除非你使用了一些奇怪的負面外觀組合,否則當前的實現將始終以它們在源代碼中的順序返回它們,但由於文檔似乎並不能保證它,這可能會在未來發生變化(例如,如果使用更高效的多線程正則表達式引擎)。即便如此,這種改變很可能會破壞很多東西,以至於只能使用某種標誌。所以假設你很安全,但這可能會改變。

相關問題