Рассмотрим следующий пример: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 "
Почему это происходит? Группа (?:=%=)?
является необязательной из-за ?
, и последняя строка в полезной нагрузке также должна присутствовать в результатах сопоставления.
положить конец линейного якоря внутри необязательной группы: '(?: =% = $)?' –
О, это работает! Но как? '' '' '' '' в многострочном режиме означает «до \ n или EOL», поэтому он должен работать в случае строки «ababaa =%», потому что необязательная часть с «=% =» недопустима, но EOL может быть достигнуто с '' '' '' '', или я могу положить «\ n» в конце. – Alex
Когда необязательная группа выходит из строя (с моим предлагаемым изменением), шаблону не нужно достигать конца строки, чтобы преуспеть, совпадение останавливается в последнем пространстве или в конце a или b, если пробелов нет. –