preg_match_all 模式中的重复模式不会导致多个 $ 匹配项
repeated pattern in preg_match_all pattern doesn't result in multiple $matches
我的脚本很简单:
<?php
$str = "mem: 9 334 23423343 3433434";
$num_matches = preg_match_all("/^mem:(\s+\d+)+$/", $str, $matches);
if (!$num_matches) {
throw new Exception("no match");
}
echo "$num_matches matches\n";
var_dump($matches);
我期望模式 (\s+\d+)+
应该匹配 $str
中的所有数字,但出于某种原因输出只显示最后一个匹配:
1 matches
array(2) {
[0] =>
array(1) {
[0] =>
string(27) "mem: 9 334 23423343 3433434"
}
[1] =>
array(1) {
[0] =>
string(8) " 3433434"
}
}
如您所见,$matches[1]
仅包含 $str
中最后出现的 \s+\d+
。我期待它应该包含所有匹配项:9, 334, 23423343, 343434
.
有没有什么方法可以改变我的模式,使它 returns 一个字符串的所有这些数字都可以包含任意数量的字符串?我认为这是 preg_match_all 的错误行为是否正确?我应该向 PHP 开发人员报告吗?
编辑:根据docs,PREG_PATTERN_ORDER的默认标志:
Orders results so that $matches[0] is an array of full pattern matches, $matches[1] is an array of strings matched by the first parenthesized subpattern, and so on.
PCRE 将最后一次出现的事件存储在重复捕获组中,因此该行为是预期的。在这种情况下,要 return 个单独的匹配项,您需要使用 \G
令牌,如下所示:
(?:^mem:|\G(?!^))\s+\K\d+
正则表达式细分:
(?:
非捕获组开始
^mem:
在输入字符串的开头匹配 mem:
|
或
\G(?!^)
从上一场比赛结束的地方开始比赛
)
非捕获组结束
\s+\K
匹配任何空格序列然后清除输出
\d+
匹配数字
PHP代码:
preg_match_all("~(?:^mem:|\G(?!^))\s+\K\d+~", $str, $matches);
我的脚本很简单:
<?php
$str = "mem: 9 334 23423343 3433434";
$num_matches = preg_match_all("/^mem:(\s+\d+)+$/", $str, $matches);
if (!$num_matches) {
throw new Exception("no match");
}
echo "$num_matches matches\n";
var_dump($matches);
我期望模式 (\s+\d+)+
应该匹配 $str
中的所有数字,但出于某种原因输出只显示最后一个匹配:
1 matches
array(2) {
[0] =>
array(1) {
[0] =>
string(27) "mem: 9 334 23423343 3433434"
}
[1] =>
array(1) {
[0] =>
string(8) " 3433434"
}
}
如您所见,$matches[1]
仅包含 $str
中最后出现的 \s+\d+
。我期待它应该包含所有匹配项:9, 334, 23423343, 343434
.
有没有什么方法可以改变我的模式,使它 returns 一个字符串的所有这些数字都可以包含任意数量的字符串?我认为这是 preg_match_all 的错误行为是否正确?我应该向 PHP 开发人员报告吗?
编辑:根据docs,PREG_PATTERN_ORDER的默认标志:
Orders results so that $matches[0] is an array of full pattern matches, $matches[1] is an array of strings matched by the first parenthesized subpattern, and so on.
PCRE 将最后一次出现的事件存储在重复捕获组中,因此该行为是预期的。在这种情况下,要 return 个单独的匹配项,您需要使用 \G
令牌,如下所示:
(?:^mem:|\G(?!^))\s+\K\d+
正则表达式细分:
(?:
非捕获组开始^mem:
在输入字符串的开头匹配mem:
|
或\G(?!^)
从上一场比赛结束的地方开始比赛
)
非捕获组结束\s+\K
匹配任何空格序列然后清除输出\d+
匹配数字
PHP代码:
preg_match_all("~(?:^mem:|\G(?!^))\s+\K\d+~", $str, $matches);