PHP preg_match: 结果中没有出现带有 + 或 * 修饰符的多组匹配?

PHP preg_match: multiple group matches with + or * modifier don't appear in result?

如果我在 PHP 中这样做:

$str = "abc pqrs-1/2&3uvw xyz";
preg_match( "/([a-z]+)([^0-9a-z][0-9])+([a-z]+)/" , $str , $m );

$m 中的匹配结果将是:

[0] => "pqrs-1/2&3uvw"
[1] => "pqrs"
[2] => "&3"
[3] => "uvw"

请注意 ([^0-9a-z][0-9])+ 部分(应该捕获 "one non-alphanumeric character followed buy one digit" 一次或多次)如何在 之外 具有 + 修饰符括弧。

显然主题字符串 $str 包含此模式的 3 个匹配项:-1/2&3 但它只记得 last一个。

有没有办法以某种方式将它们全部捕获?

我试过 preg_match_all 而不是 preg_match 但如果 entire 正则表达式在主题中匹配不止一次,那只会找到多个匹配项细绳。

用语言表达我的正则表达式的意思:

  1. 一个或多个字母
  2. 一个或多个:一个非字母数字字符后跟一个数字
  3. 一个或多个字母

所以对于上面的示例字符串,我希望结果是这样的:

[0] => "pqrs-1/2&3uvw"
[1] => "pqrs"
[2] => [ "-1" , "/2" , "&3" ]
[3] => "uvw"

但无论我尝试什么,我都无法让它也给出 -1/2 匹配项?

您不能将重复的子字符串与重复的捕获组匹配。相反,您需要使用两步法来做到这一点:

  • 使用 /([a-z]+)((?:[^0-9a-z][0-9])+)([a-z]+)/ 正则表达式匹配并捕获 ((?:[^0-9a-z][0-9])+) 所有 (?:[^0-9a-z][0-9]) 模式
  • 的重复
  • 然后,将 preg_match_all 与组模式一起使用,'/[^0-9a-z][0-9]/'

PHP demo:

$str = "abc pqrs-1/2&3uvw xyz";
if (preg_match('~([a-z]+)((?:[^0-9a-z][0-9])+)([a-z]+)~', $str, $matches)) {
    preg_match_all('~[^0-9a-z][0-9]~', $matches[2], $x);
    $matches[2] = $x[0];
}
print_r($matches);

输出:

Array
(
    [0] => pqrs-1/2&3uvw
    [1] => pqrs
    [2] => Array
        (
            [0] => -1
            [1] => /2
            [2] => &3
        )

    [3] => uvw
)