Подтвердить что ты не робот

Перекрытие совпадений в Regex

Я не могу найти ответ на эту проблему, и мне интересно, существует ли она. Упрощенный пример:

Рассмотрим строку "nnnn", где я хочу найти все совпадения "nn", но также и те, которые перекрываются друг с другом. Поэтому регулярное выражение предоставит следующие 3 совпадения:

  • пп NN
  • п NN п
  • пп пп

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

4b9b3361

Ответ 1

Возможным решением может быть использование положительного внешнего вида:

(?<=n)n

Это даст вам конечную позицию:

  • * п *** п ** пп  
  • п * п *** п ** п  
  • пп * п *** п **

Как упоминалось Тимоти Хури, позитивный взгляд более интуитивно понятен

Я предпочел бы его предложение (?=nn)n более простую форму:

(n)(?=(n))

Это будет ссылаться на первую позицию строк, которые вы хотите , и будет захватывать второе n в группе (2).

Это потому, что:

  • Любое допустимое регулярное выражение может использоваться внутри lookahead.
  • Если он содержит скобки для скобок, обратные ссылки будут сохранены.

Таким образом, группа (1) и группа (2) будут захватывать все, что 'n' представляет (даже если это сложное регулярное выражение).

Ответ 2

Использование lookahead с группой захвата работает, за счет того, что ваше регулярное выражение будет медленнее и сложнее. Альтернативное решение - указать метод Regex.Match(), где должна начинаться следующая попытка совпадения. Попробуйте следующее:

Regex regexObj = new Regex("nn");
Match matchObj = regexObj.Match(subjectString);
while (matchObj.Success) {
    matchObj = regexObj.Match(subjectString, matchObj.Index + 1); 
}

Ответ 3

AFAIK, нет простого регулярного способа сделать это сразу (т.е. вернуть три захвата, которые вы запрашиваете без цикла).

Теперь вы можете найти шаблон один раз и выполнить цикл поиска, начиная со смещения (найденная позиция + 1). Следует комбинировать регулярное выражение с простым кодом.

[EDIT] Отлично, я проиграл, когда я в основном сказал, что Ян показал...
[РЕДАКТИРОВАТЬ 2] Чтобы быть ясным: ответ Ян лучше. Не более точно, но, безусловно, более подробно, он заслуживает выбора. Я просто не понимаю, почему мой занижен, так как я до сих пор не вижу в нем ничего неправильного. Не очень, просто раздражает.