Как найти все совпадения в регулярных выражениях, если одно перекрывается или содержит другое? - PullRequest
1 голос
/ 04 февраля 2012

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

Как найти все подстроки, которые начинаются с "a" и заканчиваются "z"? Например, для "akzzaz" он должен найти "akz", "akzz", "az" и "akzzaz".

Поскольку в одной и той же позиции может быть несколько совпадений ("akz" и "akzz"), а также может быть несколько совпадений в одной и той же позиции ("az" и "akzzaz") Я не вижу, как помогает использование lookahead или lookbehind, как в упомянутой ссылке. (Также имейте в виду, что в общем случае "a" и "z" могут быть более сложными регулярными выражениями)

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

Ответы [ 4 ]

1 голос
/ 04 февраля 2012

Регулярные выражения предназначены для поиска одного совпадения за раз.Даже операция глобального сопоставления - это просто повторяющиеся применения одного и того же регулярного выражения, каждое из которых начинается в конце предыдущего совпадения в целевой строке.Так что нет, регулярные выражения не могут найти все совпадения таким образом.

Я высуну свою шею и скажу, что я не верю, что вы даже можете найти "все строки, начинающиеся с 'a' в" akzzaz'"с регулярным выражением./(a.*)/g найдет всю строку, в то время как /(a.*?)/g найдет только 'a' дважды.

Я бы запрограммировал это, чтобы найти все 'a' и найти каждую из подстрок оттуда доконец строки для всех Z.Поэтому ищите «akzzaz» и «az» для «z», давая «akz», «akzz», «akzzaz» и «az».Это довольно простая вещь, но не работа для регулярных выражений, если фактические токены 'a' и 'z' не сложны.

1 голос
/ 04 февраля 2012

Для вашей текущей проблемы лучше работать с string.startwith и string.endwith.Регулярное выражение не обязательно быстрее во всех случаях.

0 голосов
/ 20 февраля 2013

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

(? = (\ Ш +)).

Это регулярное выражение использует группы захвата внутри утверждения нулевой ширины, и для каждого совпадения в позиции i (каждый символ) группа захвата является подстрокой длины n-i.
Выполнение всего, что потребовало бы, чтобы механизм регулярных выражений оставался на том же месте после сопоставления, вероятно, излишне для подхода с регулярными выражениями.

0 голосов
/ 04 февраля 2012

Попробуйте это регулярное выражение

a[akz]+z - in case a, k and z are the only characters
a[a-z]+z - in case of any alphabet
...