代码之家  ›  专栏  ›  技术社区  ›  RocketNuts

PHP preg_匹配:结果中不显示带+或*修饰符的多组匹配?

  •  2
  • RocketNuts  · 技术社区  · 5 年前

    如果我在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])+ 该部分应该捕获“一个非字母数字字符后跟一个数字”一次或多次,具有 + 修饰语 外部 括号。

    显然是主语字符串 $str -1 /2 &3 但它只记得 最后的

    有没有办法抓住他们?

    我试过了 preg_match_all preg_match 但只有当 全部的 正则表达式在主题字符串中多次匹配。

    要表达正则表达式的含义,请执行以下操作:

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

    因此,对于上面的示例字符串,我希望结果如下:

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

    但不管我怎么做,我都无法让它也给出 /2

    1 回复  |  直到 5 年前
        1
  •  1
  •   Wiktor Stribiżew    5 年前

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

    • 使用 /([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
    )