Перекрытие совпадений в Regex
Я не могу найти ответ на эту проблему, и мне интересно, существует ли она. Упрощенный пример:
Рассмотрим строку "nnnn", где я хочу найти все совпадения "nn", но также и те, которые перекрываются друг с другом. Поэтому регулярное выражение предоставит следующие 3 совпадения:
Я понимаю, что это не совсем то, для чего предназначены регулярные выражения, но ходьба по строке и синтаксический анализ этого вручную кажутся очень сложным кодом, учитывая, что на самом деле совпадения должны выполняться с использованием шаблона, а не буквальной строки.
Ответы
Ответ 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] Чтобы быть ясным: ответ Ян лучше. Не более точно, но, безусловно, более подробно, он заслуживает выбора. Я просто не понимаю, почему мой занижен, так как я до сих пор не вижу в нем ничего неправильного. Не очень, просто раздражает.