2015-11-06 75 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

不,没有保证。它会按照它想要的顺序返回它们,尽管它通常会按照它们被发现的顺序返回它们。可能有些例子没有。如果订单绝对重要,则根据找到的地点对匹配进行排序。这就是说,我相信,除非你使用了一些奇怪的负面外观组合,否则当前的实现将始终以它们在源代码中的顺序返回它们,但由于文档似乎并不能保证它,这可能会在未来发生变化(例如,如果使用更高效的多线程正则表达式引擎)。即便如此,这种改变很可能会破坏很多东西,以至于只能使用某种标志。所以假设你很安全,但这可能会改变。

相关问题