.NET(我使用的是4.5.2)中的正则表达式似乎具有三种(非静态)匹配方法:


regex.Match(string input)搜索input中的第一个匹配项。
regex.Match(string input, int startIndex)input开始搜索startIndex中的第一个匹配项。
regex.Match(string input, int startIndex, int length)在由inputstartIndex定义的length范围内搜索第一个匹配项。


如果我写

System.Text.RegularExpressions.Regex regex =
    new System.Text.RegularExpressions.Regex("^abc");
string str = "abc abc";

System.Text.RegularExpressions.Match match = regex.Match(str);
System.Diagnostics.Debug.WriteLine(match.Success);


然后我看到match.SuccessTrue,正如预期的那样。 regexabc开头的str匹配。

如果我再写

int index = 4;
match = regex.Match(str, index);
System.Diagnostics.Debug.WriteLine(match.Success);


从索引4到str的末尾搜索,那么我看到match.SuccessFalse,正如预期的那样。在abc的索引4处有一个str,但索引4不是字符串的开头。

但是,如果我写

match = regex.Match(str, index, str.Length - index);
System.Diagnostics.Debug.WriteLine(match.Success);
System.Diagnostics.Debug.WriteLine(match.Index);


再次从索引4搜索到str的末尾,那么我发现match.Success意外地是True,而match.Index是4。我希望得到与调用regex.Match(str, index)相同的结果。

是否有办法在.NET Regex Match方法中获得一致的字符串起始锚行为?

最佳答案

Regex.cs source code中的注释中,我看到public Match Match(String input, int startat)找到从指定位置开始的第一个匹配项,而public Match Match(String input, int beginning, int length)找到第一个匹配项,将搜索限制在char数组的指定间隔内。

结合测试结果(和mine),很明显,Regex.Match方法的最后一次重载将子字符串作为一个新的单独的字符串,并将其传递给regex引擎。将^更改为\A不会有帮助。

因此,要知道匹配项是否是真正的开始,您应该在自己的代码中添加逻辑,例如,如果index大于0,则所有匹配项都不是字符串的真正开始。但是,返回的索引是正确的,因此对我来说似乎是个错误。

09-10 11:19
查看更多