. net Regex, чтобы смотреть в будущее и заранее исключать строки, которые не содержат определенных символов - PullRequest
1 голос
/ 17 марта 2020

Я использую. Net Аромат регулярных выражений.

Предположим, у меня есть строка 123456789AB, и я хочу сопоставить AB (может быть любые две заглавные буквы), только если часть строки, содержащая числа (123456789) имеет 5 и 8 в нем. Так что я придумал (? = 5) (? = 8) ([AZ] {2}) Но это не работает. После некоторой ошибки в RegexStorm

я получил (? = (. * 5)) (? = (. * 8)) [AZ] {2}

Что я ожидаю, так это сопоставление начнется с начала строки, поскольку при просмотре вперед не используются никакие символы. Но часть "[AZ] {2}" не перемещается вперед, чтобы соответствовать AB во входной строке. Мой вопрос: почему это так? я знаю, что заменив его на. * [AZ] {2} заставит его двигаться вперед, но тогда в строке соответствия есть вся строка. Какое решение в этом случае, кроме помещения части слова ([AZ] {2}) в отдельную группу, а затем перехвата только этой группы.

Ответы [ 2 ]

1 голос
/ 17 марта 2020

Lookaheads проверяет совпадение с образцом непосредственно справа от текущей позиции в строке. (?=(.*5))(?=(.*8)) соответствует местоположению, за которым сразу следует 0 или более символов, кроме символов разрыва строки, как можно больше, а затем 5, а затем - в той же позиции - еще одна аналогичная проверка, если она выполняется, но для нее требуется 8 после любого нуля или больше символов, столько, сколько возможно.

Вы можете использовать до lookbehinds столько, сколько требуется подстрок перед двумя буквами:

(?s)(?<=5.*?)(?<=8.*?)[A-Z]{2}

См. regex demo

Подробности

  • (?s) - позволяет . соответствовать символам новой строки
  • (?<=5.*?) - местоположение, которому непосредственно предшествует 5, а затем 0 или более символов как можно меньше
  • (?<=8.*?) - местоположение, которому непосредственно предшествует 8, а затем 0 или более символов как можно меньше
  • [A-Z]{2} - две заглавные буквы ASCII.
0 голосов
/ 17 марта 2020

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

(?<=\b[^58]*?(?:5[^8]*8|8[^5]*5)[^A-Z]*?)[A-Z]{2}
...