#regex #pcre
Вопрос:
У меня есть числа, разделенные запятыми, я хочу сопоставить каждый элемент после START
или до END
, если существует какое-либо ключевое слово.
Я правильно понял большинство тестовых случаев, используя
(?:.*?START|END.*)(*SKIP)(*F)|d
за исключением тех, которые START
появляются после END
или нескольких экземпляров START
и END
существуют.
вход | Матчи |
---|---|
123,45678,789,777,888,1234 |
123 , 45678 , 789 , 777 , 888 , 1234 |
123,START,789,777,888,1234 |
789 , 777 , 888 , 1234 |
123,45678,789,777,END,1234 |
123 , 45678 , 789 , 777 |
123,START,789,777,END,1234 |
789 , 777 |
123,END,789,777,START,1234 |
123 |
123,START,789,START,777,END,1234 |
789 , 777 |
123,START,789,END,777,END,1234 |
789 |
123,END,789,START,777,END,1234 |
123 |
Вот проект regex101, который я пробовал, я использую PCRE2(PHP7.3).
Комментарии:
1. Вы можете уточнить
123,START,789,START,777,END,1234
требования?2. Что непонятно?
789
и777
ожидаются, поскольку они появляются после первого появленияSTART
и до первого появленияEND
.3. @anubhava, пока их несколько
START
илиEND
существует. Всегда используйте первый и игнорируйте дальнейшие экземпляры.
Ответ №1:
Вы можете исправить свой шаблон, добавив ограничение, чтобы найти START
то, чего END
до него не было:
(?:^(?:(?!END).)*?START|END.*)(*SKIP)(*F)|d
// ^^^^^^^^^^^^^^^
Смотрите демонстрацию регулярных выражений.
Здесь ^(?:(?!END).)*?START
(вместо .*?START
) совпадений
^
— начало строки(?:(?!END).)*?
— любые символы, кроме символов разрыва строки, как можно меньше, которые не запускают последовательностьEND
символовSTART
—START
последовательность символов.
Вы также можете использовать
(?:G(?!A)|^(?:(?:(?!END).)*?START)?)(?:(?!END).)*?Kd
Смотрите демонстрацию регулярных выражений.
Подробные сведения:
(?:G(?!A)|^(?:(?:(?!END).)*?START)?)
— либо конец предыдущего успешного совпадения (G(?!A)
), либо (|
) начало строки (^
), а затем необязательное вхождение любого текста до первого вхожденияSTART
, которому не предшествуетEND
((?:(?:(?!END).)*?START)?
)(?:(?!END).)*?
— любой символ, кроме символов разрыва строки, ноль или более раз, но как можно меньше, который не запускает последовательностьEND
символовK
— оператор сброса соответствия, который удаляет весь текст, сопоставленный до сих пор, из общего буфера памяти соответствияd
— одна или несколько цифр.