Многострочный режим Regex с опциональным пропуском групповых данных

Рассмотрим следующий пример:

$payload = '
ababaaabbb =%=
ababaaabbb =%=
ababaa     =%=
';

$pattern = '/^[ab]+\s*(?:=%=)?$/m';
preg_match_all($pattern, $payload, $matches);
var_dump($matches);

Ожидаемый и фактический результат матча:

"ababaaabbb =%=""ababaaabbb =%=""ababaa     =%="

Но если $payload изменился на

$payload = '
ababaaabbb =%=
ababaaabbb =%=
ababaa     =%'; // "=" sign removed at EOL

фактический результат

"ababaaabbb =%=""ababaaabbb =%="

но ожидается

"ababaaabbb =%=""ababaaabbb =%=""ababaa     "

Почему это случилось? группа (?:=%=)? необязательно из-за ? и последняя строка в полезной нагрузке также должна присутствовать в результатах поиска.

1

Решение

Посмотрите на свой текущий график регулярных выражений:

введите описание изображения здесь

=%= является необязательно (посмотрите, как ветка между white space а также End of line вилки) но ЭОЛ необходимо. Это означает после одного или нескольких a или же b символы и ноль или более пробелов, EOL должен произойти. Тем не менее, у вас есть =% на вашей 3-й строке => НЕТ.

Теперь, когда вы перемещаете $ привязка к необязательной группе:

введите описание изображения здесь

Конец строки сейчас необязательный, тоже, и матч будет возвращен после соответствия 1+ a или же b символы и дополнительные пробелы.

1

Другие решения

Поскольку последняя строка заканчивается =%, ты должен сделать последний = также необязательно и используйте группу захвата для ожидаемых данных:

/^([ab]+\s*)(?:=%=?)?$/m

RegEx Demo

PS: Ваш ожидаемый результат доступен в захваченной группе № 1

0

Группа (?:=%=)? не является обязательным в вашем регулярном выражении. Тот не означает, что каждая часть этой группы также является необязательной.

Ваше регулярное выражение работает, только если он видит строку aс и bs, необязательный пробел, затем либо (1) =%= и конец строки или (2) только конец строки. Это не будет работать, если он видит строку aс и bs, пробел, то что-нибудь кроме =%= или конец строки. Так, =% не сработает

Чтобы выполнить то, что вы, очевидно, хотите сделать, вам нужно сделать второй = необязательно, вот так:

$pattern = '/^[ab]+\s*(?:=%=?)?$/m';
// see the additional ? here^

Но, похоже, ты не хочешь =% совсем в этом сценарии, что означает, что вам нужно стать еще более креативным:

$pattern = '/^[ab]+\s*(?:(?:=%=)?$|(?==%$))/m';

демонстрация.

0
По вопросам рекламы [email protected]