我正在使用Regex.Matches()来解析大型文本文件中的一堆匹配。
是否有关于此函数的任何文档可以保证Matches数组中的第一项与文本中的第一项匹配,Matches数组中的第二项与文本中的第二项匹配,依此类推?
基于Regex.Match的文档似乎有很多暗示,但我无法找到证据证明Regex.Matches将始终按照文本中找到的顺序返回匹配。
修改
我发现了一个简洁的网站,允许您浏览.NET源代码。
我们看到匹配会返回一个新的MatchCollection,它不会执行任何操作,因为它会延迟执行直到它被使用。
我们看到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);
这对我来说足够了。
答案 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)
不,没有保证。它将按照它想要的顺序返回它们,尽管它通常会按照它们被找到的顺序返回它们。可能有一些例子没有。如果订单绝对重要,则根据匹配的位置对匹配进行排序。
那就是说,我相信除非你使用一些奇怪的负面观察组合,否则当前的实现将始终按照它们在源中的顺序返回它们,但是由于文档似乎不能保证它,可能会在将来发生变化(例如,如果使用更高效的多线程正则表达式引擎)。即便如此,这种类型的改变很可能会打破这么多东西,只会通过某种标志启用它。所以假设你很安全,但这可能会改变。