Перекрывающиеся совпадения в Regex
Вопрос
Кажется, я не могу найти ответ на эту проблему, и мне интересно, существует ли он.Упрощенный пример:
Рассмотрим строку «nnnn», в которой я хочу найти все совпадения «nn», а также те, которые перекрываются друг с другом.Таким образом, регулярное выражение предоставит следующие 3 совпадения:
- пппп
- нппн
- пппп
Я понимаю, что это не совсем то, для чего предназначены регулярные выражения, но обход строки и ее анализ вручную кажутся очень большим объемом кода, учитывая, что на самом деле совпадения должны быть выполнены с использованием шаблона, а не буквальной строки.
Решение
Возможным решением может быть использование позитивный взгляд позади:
(?<=n)n
Это даст вам конечную позицию:
- *н***н**нн
- н*н***н**н
- нн*н***н**
Как упоминал Тимоти Хури, а позитивный прогноз является более интуитивным
Я бы предпочел его предложение (?=nn)n
более простая форма:
(n)(?=(n))
Это будет отсылать к первая позиция строк, которые вы хотите и захватит второе n в группе (2).
Это так, потому что:
- Внутри просмотра вперед можно использовать любое допустимое регулярное выражение.
- Если он содержит скобки, то обратные ссылки будут сохранены.
Таким образом, group(1) и group(2) будут фиксировать все, что представляет собой n (даже если это сложное регулярное выражение).
Другие советы
Использование опережающего просмотра с группой захвата работает за счет того, что регулярное выражение становится медленнее и сложнее.Альтернативное решение — сообщить методу Regex.Match(), где должна начаться следующая попытка сопоставления.Попробуй это:
Regex regexObj = new Regex("nn");
Match matchObj = regexObj.Match(subjectString);
while (matchObj.Success) {
matchObj = regexObj.Match(subjectString, matchObj.Index + 1);
}
AFAIK, не существует чистого регулярного способа сделать это сразу (т.возврат трех запрошенных вами снимков без цикла).
Теперь вы можете найти шаблон один раз и продолжить поиск, начиная со смещения (найденная позиция + 1).Следует сочетать использование регулярных выражений с простым кодом.
[РЕДАКТИРОВАТЬ] Отлично, меня минусовали, когда я в основном сказал то, что показал Ян...
[РЕДАКТИРОВАТЬ 2] Чтобы внести ясность:Ответ Яна лучше.Не более точный, но, безусловно, более подробный, он заслуживает того, чтобы его выбрали.Я просто не понимаю, почему за мой минус проголосовали, ведь я по-прежнему не вижу в нем ничего неправильного.Ничего страшного, просто раздражает.