2013-06-28 8 views
2

Учитывая этот вход: 123456789 Мне нужно регулярное выражение, которое будет добываться MatchCollection со следующими match.Value с: 123; 234; 345; 456; 567; 678; 789скольжения Синтаксиса регулярных выражений C#

До сих пор я пытался использовать «обратную ссылку», жадное, группирование, и т. д., но не повезло. Очевидно, я слишком тупой, чтобы найти решение самостоятельно.

+3

почему регулярное выражение? Существует гораздо более простой способ достижения такого результата. –

+1

@Garath. Он также применяется в местах с более сложными выражениями, которые могут быть недоступны в противном случае. – Rawling

+0

@Garath, Rawilng - это правильно. я только упростил «атомарное» регулярное выражение до (\ d {3}), чтобы он был коротким и увеличил фокус на «скользящем» поведении. (подробности, если вы действительно этого хотите: фактическая ситуация: мне нужно идентифицировать номера кредитных карт, встроенных в строку цифр) Спасибо! –

ответ

4

Матчи не могут пересекаться. Но вы могли бы получить те в 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 регулярное выражение во втором, вы можете просто использовать произвольное выражение сразу.

+0

СПАСИБО МНОГО! Я принял ваше первое предложение и добавил только одну закрывающую скобку (для закрытия foreach), только маленькую крошечную коррекцию. Затем заменил. {3} на «реальное» регулярное выражение, которое будет соответствовать номеру кредитной карты, и проверит, что он работает отлично. –

+0

@ пользователь996605 добро пожаловать. исправлена ​​эта скобка;) –

5

Ну, вы можете сделать это с помощью positive lookahead assertions в сочетании с capturing group:

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

Вы должны смотреть на каждый матч-х .Groups[1].Value.

+0

ahhh, избили меня до 36 секунд;) –

+0

gr ..... Я попытался сделать это в JS 'alert ('123456789' .match (/ [0-9] {3}/ig))' но он не перекрывается .... –

+2

@RoyiNamir: Э-э, это совершенно другое регулярное выражение. Конечно, это не перекрывается. Вы не используете lookahead. –

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); 
} 
+0

, пожалуйста, обратитесь к другим ответам (например, Rawling). Ядровое регулярное выражение было упрощено только для чтения. Мне не нужно получить подстроку. Реальный случай НУЖДАЕТ регулярное выражение. –