Матчи не могут пересекаться. Но вы могли бы получить те в Group
вместо:
foreach (Match m in Regex.Matches("123456789", @"(?=(.{3}))."))
{
Console.WriteLine(m.Groups[1].Value);
}
Хитрость здесь сочетание lookahead и capturing group. Обратите внимание, что конечный .
на самом деле не нужен, потому что двигатель будет продвигать начальное положение хотя бы одним символом в любом случае, но я думаю, что это делает намерение более ясным. Также обратите внимание, что если ваш вход содержит разрывы строк, вам нужно либо опустить этот трейлинг .
, либо использовать [\s\S]
, либо использовать RegexOptions.Singleline
.
В качестве альтернативы, вы можете использовать Match()
overload that takes an offset:
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));
}
Конечно, первые два подхода легко обобщают на более сложное регулярное выражение (в то время как третье нет): в первом вы можете заменить содержимое lookahead на арбитраж ry регулярное выражение во втором, вы можете просто использовать произвольное выражение сразу.
почему регулярное выражение? Существует гораздо более простой способ достижения такого результата. –
@Garath. Он также применяется в местах с более сложными выражениями, которые могут быть недоступны в противном случае. – Rawling
@Garath, Rawilng - это правильно. я только упростил «атомарное» регулярное выражение до (\ d {3}), чтобы он был коротким и увеличил фокус на «скользящем» поведении. (подробности, если вы действительно этого хотите: фактическая ситуация: мне нужно идентифицировать номера кредитных карт, встроенных в строку цифр) Спасибо! –