Захватить поток цифр, за которым не следуют определенные цифры - PullRequest
0 голосов
/ 11 мая 2018

Я хотел захватить поток цифр, за которыми не следуют определенные цифры. Например

input = abcdef lookbehind 123456..... asjdnasdh lookbehind 789432

Я хочу захватить 789432, а не 123 , используя только отрицательный прогноз .

Я пытался (?<=lookbehind )([\d])+(?!456), но он захватывает 123456 и 789432.

Использование (?<=lookbehind )([\d])+?(?!456) захватывает только 1 и 7.

Группировка для меня не вариант, так как мой вариант использования не позволяет мне это сделать.

Можно ли как-нибудь захватить 789432, а не 123 с использованием чистого регулярного выражения? Объяснение ответа приветствуется.

Ответы [ 2 ]

0 голосов
/ 11 мая 2018

Вы можете использовать квантификатор притяжений с отрицательным взглядом

(?<=lookbehind )\d++(?<!456)
                  ^^ ^^^^^^ 

См. это демо регулярных выражений .

Синоним шаблона с атомарной группой:

(?<=lookbehind )(?>\d+)(?<!456)

информация

  • (?<=lookbehind ) - положительный взгляд сзади, который соответствует местоположению в строке, которому непосредственно предшествует lookbehind
  • \d++ - Собственно совпадают 1+ цифр, что не позволяет вернуться к шаблону (двигатель не может повторить сопоставление с любой цифрой, совпадающей с \d++)
  • (?<!456) - проверка с отрицательным взглядом, которая не соответствует совпадению, если последние 3 цифры, совпадающие с \d++, равны 456.

Почему смотреть назад и почему не смотреть вперед

Отрицательный взгляд позади (?<!...) гарантирует, что определенный шаблон не будет совпадать непосредственно слева от текущего местоположения. Отрицательный прогноз (?!...) проваливает совпадение, если его шаблон совпадает сразу справа от текущего местоположения. «Fail» в данном случае означает, что механизм регулярных выражений отказывается от текущего способа сопоставления строки, и, если перед просмотром сзади / просмотром есть количественные шаблоны, механизм может вернуть обратно в эти шаблоны, чтобы попытаться сопоставить строку по-разному. Обратите внимание, что здесь собственнический квантификатор делает невозможным для движка выполнить проверку просмотра несколько раз 456, она выполняется только после того, как все цифры будут получены с помощью \d++.

Вы (?<=lookbehind )([\d])+(?!456) регулярное выражение соответствует 123456, потому что \d+ сопоставляет эти цифры жадным образом (все сразу) и (?!456) проверяет 456 после них, и поскольку там нет 456 , матч возвращается. (?<=lookbehind )([\d])+?(?!456) соответствует только одной цифре, потому что \d+? соответствует ленивому способу, 1 цифре соответствует, и затем выполняется проверка loolahead. Поскольку 456 после 1 нет, 1 возвращается.

почему ++ собственнический квантификатор

Он не позволяет обработчику регулярных выражений повторять сопоставление строки по-разному, если ранее были определены количественные шаблоны. Итак, (?<=lookbehind )\d+(?<!456) соответствует 12345 в 123456, поскольку 456 до 6.

нет
0 голосов
/ 11 мая 2018

Вы также можете использовать отрицательный взгляд:

(?<=lookbehind )\d+\b(?<!456)

RegEx Demo

Информация о регулярных платежах:

  • (?<=lookbehind ): позитивный взгляд за то, что мы имеем "lookbehind " перед текущей позицией
  • \d+\b: соответствуют 1+ цифрам, за которыми следует граница слова
  • (?<!456): отрицательный взгляд, подтверждающий, что у нас нет 456 до текущей позиции

Альтернативное решение с отрицательным прогнозом:

(?<=lookbehind )(?!\d*456)\d+

RegEx Demo 2

Нам нужно \d* в выражении предпросмотра (?!\d*456), чтобы мы могли пропустить 456 после сопоставления 0 или более цифр из текущей позиции.

...