如何在php中使用J修饰符?

如何在php中使用J修饰符?,php,regex,Php,Regex,来自php文档 J (PCRE_INFO_JCHANGED) The (?J) internal option setting changes the local PCRE_DUPNAMES option. Allow duplicate names for subpatterns. 因此J Modifier允许在命名的CAPTRUNG组中使用重复的名称。请参见演示中右侧的匹配信息 当我试图在php中检查这个修饰符时,它会显示下面的警告,并且不会显示任何输出 PHP War

来自php文档

J (PCRE_INFO_JCHANGED)
    The (?J) internal option setting changes the local PCRE_DUPNAMES option. 
    Allow duplicate names for subpatterns. 
因此J Modifier允许在命名的CAPTRUNG组中使用重复的名称。请参见演示中右侧的匹配信息

当我试图在php中检查这个修饰符时,它会显示下面的警告,并且不会显示任何输出

PHP Warning:  preg_match_all(): Unknown modifier 'J'
这是我的密码

$str = "foobarbuzxxxxx";
preg_match_all('~(?<name>foo).*?(?<name>buz)~J', $str, $match);
print_r($match);
输出:

Array
(
    [0] => Array
        (
            [0] => foobarbuz
        )

    [name] => Array
        (
            [0] => buz
        )

    [1] => Array
        (
            [0] => foo
        )

    [2] => Array
        (
            [0] => buz
        )

)
您是否看到
名称
仅是第二组而不是第一组的索引。但我们都用一个名字来定义。它清楚地表明,有两个不同的组具有相同的名称,称为
name
。但是在php中,
print\r($match['name'])仅打印第二组

Array
(
    [0] => buz
)
但不是第一个。为什么?我假设如果我们做
print\r($match['name']),它将同时显示两者,但不显示第一个

因此,关于在PHP中使用
J
修饰符,我的两个问题是

  • 为什么它指的是第二组而不是两组?如果它总是指最后一个组,那么在捕获组中需要重复的名称吗

  • 还有,为什么在php分隔符之后添加
    J
    修饰符会显示警告(不起作用)

  • 因为数组不能包含两个相等的键。这就是为什么“name”键位于第一位,但具有最后一个值(它被重新分配)

  • 目前,您只能在模式中使用由(?J)更改的PCRE_INFO_jc。 我曾多次向维护人员提出建议,但它不接受 将“J”作为扩展名中的有效修饰符

    此修饰符的用法示例

    preg_match_all('/(?J)(?<string>.*)1|(?<string>.*)2|(?<string>.*)3$/', "text2\npext3", $matches, PREG_SET_ORDER);
    var_dump($matches);
    
    preg_match_all('/(?J)(?<string>.*)1|(?<string>.*)2|(?<string>.*)3$/', "text2\npext3", $matches);
    var_dump($matches);
    
    preg_match_all('/(?J)(?*)1 |(?*)2 |(?*)3$/',“text2\npext3”,$matches,preg_SET_顺序);
    var_dump($matches);
    preg_match_all('/(?J)(?*)1 |(?*)2 |(?*)3$/',“text2\npext3”,$matches);
    var_dump($matches);
    

    那么
    J
    修饰符的用途是什么?@AvinashRaj您可以在替代分支和PREG_SET_ORDER选项中使用重复名称。如果您有不同的“或”ed模式(使用管道“|”),则使用此类修饰符可能很有用使用相同的名称,并且您希望在给定的模式下始终至少有一个匹配
    name
    ,正如@sectus使用PREG\u SET\u顺序所说的那样。这应该是公认的答案。
    preg_match_all('/(?J)(?<string>.*)1|(?<string>.*)2|(?<string>.*)3$/', "text2\npext3", $matches, PREG_SET_ORDER);
    var_dump($matches);
    
    preg_match_all('/(?J)(?<string>.*)1|(?<string>.*)2|(?<string>.*)3$/', "text2\npext3", $matches);
    var_dump($matches);