【发布时间】:2017-06-26 13:25:27
【问题描述】:
考虑下一个例子:
$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”放在最后。 -
当可选组失败(我建议的更改)时,模式不需要到达行尾即可成功,匹配停止在最后一个空格或最后一个 a 或 b如果没有空格。
-
对我来说很奇怪:我认为如果可选(原文如此!)组匹配失败,则匹配继续进行,但不会在第一次失败时停止。
-
哦,由于meta.stackexchange.com/questions/1555/…,我无法将您的评论标记为正确答案也许,您将其移至此处的单独帖子,我将其标记为解决方案?
标签: php regex preg-match-all pcre multiline