考虑下一个例子:
let init n ~f =
if n < 0 then raise (Invalid_argument "init");
let rec loop i accum =
if i = 0 then accum
else loop (i-1) (f (i-1) :: accum)
in
loop n []
;;
匹配的预期和实际结果是:
$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 "
,组(?:=%=)?
是可选的,有效负载中的最后一个字符串也应出现在匹配结果中。
答案 0 :(得分:1)
查看当前的正则表达式图:
=%=
是可选的(请参阅white space
和End of line
分叉之间的分支),但需要EOL 。这意味着在一个或多个a
或b
符号之后,以及零个或多个空格,必须出现EOL 。但是,您的第3行有=%
=&gt;没有比赛。
现在,当您将$
锚点移动到可选组中时:
行尾也是可选,匹配1 + a
或b
字符和可选空格后会返回匹配。
答案 1 :(得分:0)
答案 2 :(得分:0)
小组(?:=%=)?
在正则表达式中是可选的。 不意味着该组的每个部分也是可选的。
你的正则表达式只有在它看到一串a
s和b
s,可选空格,然后是(1)=%=
和行尾或(2)时才有效只是结束了。如果它看到一串a
s和b
s,空格,那么除了=%=
以外的任何内容或该行的结尾都不会起作用。因此,=%
无法工作。
要完成您显然想做的事情,您需要使第二个=
可选,如下所示:
$pattern = '/^[ab]+\s*(?:=%=?)?$/m';
// see the additional ? here^
但在这种情况下,您似乎并不想要=%
,这意味着您需要获得更多创意:
$pattern = '/^[ab]+\s*(?:(?:=%=)?$|(?==%$))/m';