从C#的Regex.Matches返回的数组的顺序是否保证符合文本的顺序?

时间:2015-11-06 18:56:07

标签: c# regex

我正在使用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函数按文本的顺序运行正则表达式,在每个匹配进入主arraylist时添加它们。

Match match;

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

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

        _matches.Add(match);

这对我来说足够了。

2 个答案:

答案 0 :(得分: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 :(得分:-1)

不,没有保证。它将按照它想要的顺序返回它们,尽管它通常会按照它们被找到的顺序返回它们。可能有一些例子没有。如果订单绝对重要,则根据匹配的位置对匹配进行排序。

那就是说,我相信除非你使用一些奇怪的负面观察组合,否则当前的实现将始终按照它们在源中的顺序返回它们,但是由于文档似乎不能保证它,可能会在将来发生变化(例如,如果使用更高效的多线程正则表达式引擎)。即便如此,这种类型的改变很可能会打破这么多东西,只会通过某种标志启用它。所以假设你很安全,但这可能会改变。