Рассмотрим следующий пример:
$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 "
Почему это случилось? группа (?:=%=)?
необязательно из-за ?
и последняя строка в полезной нагрузке также должна присутствовать в результатах поиска.
Посмотрите на свой текущий график регулярных выражений:
=%=
является необязательно (посмотрите, как ветка между white space
а также End of line
вилки) но ЭОЛ необходимо. Это означает после одного или нескольких a
или же b
символы и ноль или более пробелов, EOL должен произойти. Тем не менее, у вас есть =%
на вашей 3-й строке => НЕТ.
Теперь, когда вы перемещаете $
привязка к необязательной группе:
Конец строки сейчас необязательный, тоже, и матч будет возвращен после соответствия 1+ a
или же b
символы и дополнительные пробелы.
Поскольку последняя строка заканчивается =%
, ты должен сделать последний =
также необязательно и используйте группу захвата для ожидаемых данных:
/^([ab]+\s*)(?:=%=?)?$/m
PS: Ваш ожидаемый результат доступен в захваченной группе № 1
Группа (?:=%=)?
не является обязательным в вашем регулярном выражении. Тот не означает, что каждая часть этой группы также является необязательной.
Ваше регулярное выражение работает, только если он видит строку a
с и b
s, необязательный пробел, затем либо (1) =%=
и конец строки или (2) только конец строки. Это не будет работать, если он видит строку a
с и b
s, пробел, то что-нибудь кроме =%=
или конец строки. Так, =%
не сработает
Чтобы выполнить то, что вы, очевидно, хотите сделать, вам нужно сделать второй =
необязательно, вот так:
$pattern = '/^[ab]+\s*(?:=%=?)?$/m';
// see the additional ? here^
Но, похоже, ты не хочешь =%
совсем в этом сценарии, что означает, что вам нужно стать еще более креативным:
$pattern = '/^[ab]+\s*(?:(?:=%=)?$|(?==%$))/m';