2

鉴于此输入:123456789 我需要一个正则表达式,它将产生MatchCollection具有以下match.Values 的 a: 123; 234; 345; 456; 567; 678; 789

到目前为止,我尝试使用“反向引用”、贪婪、分组等,但没有运气。显然我太笨了,无法自己找到解决方案。

4

3 回答 3

5

好吧,您可以使用积极的前瞻断言捕获组来做到这一点:

Regex regexObj = new Regex(@"(?=(\d{3}))");

您需要查看每场比赛的.Groups[1].Value.

于 2013-06-28T11:58:39.550 回答
4

匹配不能重叠。但是你可以把它们Group换成:

foreach (Match m in Regex.Matches("123456789", @"(?=(.{3}))."))
{
    Console.WriteLine(m.Groups[1].Value);
}

这里的技巧是前瞻捕获组的组合。请注意,尾随.并不是真正必要的,因为无论如何引擎都会将起始位置至少提前一个字符,但我认为它使意图更加清晰。另请注意,如果您的输入包含换行符,您将希望省略尾随.[\s\S]改用或使用RegexOptions.Singleline.

或者,您可以使用Match()带偏移量的重载

Regex r = new Regex(@".{3}");
for (int i = 0; i < input.Length; i++)
{
    Match m = r.Match(input, i);
    if(m.Success)
        Console.WriteLine(m.Value);
}

但这既不给你,MatchCollection也不证明使用正则表达式是合理的,因为你Substring现在也可以使用:

for (int i = 0; i < input.Length - 2; i++)
{
    Console.WriteLine(input.Substring(i, 3));
}

当然,前两种方法很容易推广到更复杂的正则表达式(而第三种方法则不然):在第一种方法中,您可以用任意正则表达式替换前瞻的内容,在第二种方法中,您可以使用立即任意表达。

于 2013-06-28T11:59:15.837 回答
1

不需要正则表达式:

string str = "123456789";
var threes = Enumerable.Range(0, str.Length - 2)
                       .Select(i => str.Substring(i, 3));
foreach (var item in threes)
{
    Console.WriteLine(item);
}
于 2013-06-28T12:41:43.937 回答