在preg_match_all模式重复模式不会导致多$比赛

问题描述 投票:0回答:1

我的剧本很简单:

<?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]只包含\s+\d+最后$str发生。我期待它应该包含所有的比赛的:9, 334, 23423343, 343434

是否有某种方式来改变我的模式,使得它返回所有这些数字对于可能包含字符串任意数量的字符串?我在想这是preg_match_all不正确的行为是否正确?我应该报告给PHP开发者?

编辑:根据docs,PREG_PATTERN_ORDER的默认标志:

结果排序使得$ matches [0]被满图案匹配的数组,$匹配[1]是第一个括号子模式匹配的字符串的数组,等等。

php regex preg-match-all
1个回答
2
投票

PCRE这样的行为,预计存储在重复捕获组最后一次出现。在这种情况下返回个人比赛中,你需要\G令牌作为以下工作:

(?:^mem:|\G(?!^))\s+\K\d+

See live demo

正则表达式崩溃:

  • qazxsw POI非捕获组的开始 qazxsw POI匹配qazxsw POI在输入字符串的开始 (?:或者 ^mem:开始从那里以前比赛结束的比赛
  • 非捕获组mem:
  • |匹配空格,然后清除输出的任何序列
  • \G(?!^)匹配位数

PHP代码:

)
© www.soinside.com 2019 - 2024. All rights reserved.