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

时间:2015-02-08 05:05:16

标签: php regex

来自php docs

J (PCRE_INFO_JCHANGED)
    The (?J) internal option setting changes the local PCRE_DUPNAMES option. 
    Allow duplicate names for subpatterns. 

所以J modifer允许在命名的captruing组中重复名称。请参阅this演示文稿右侧的匹配信息。

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

PHP Warning:  preg_match_all(): Unknown modifier 'J'

这是我的代码,

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

然后我可以通过在正则表达式中添加J修饰符来解决这个问题,例如,

'~(?J)(?<name>foo).*?(?<name>buz)~'

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

输出:

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

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

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

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

)

您是否看到name仅是第二组而非第一组的索引。但我们在一个名称下定义两者。在this中,它清楚地表明有两个名为name的同名组。但在php中,print_r($match['name']);仅打印第二组

Array
(
    [0] => buz
)

但不是第一个。为什么?我假设如果我们print_r($match['name']);,它会显示两者,但不会显示第一个。

所以关于在PHP中使用J修饰符的两个问题是,

  1. 为什么它引用第二组而不是两者?如果它总是引用最后一组,那么捕获组中重复名称的需要是什么?

  2. 还有为什么在php分隔符后显示警告(无法正常工作)后添加J修饰符?

1 个答案:

答案 0 :(得分:3)

  1. 因为数组不能包含两个相等的键。这就是为什么'name'键首先出现,但是有最后一个值(它被重新分配)。

  2. https://bugs.php.net/bug.php?id=47456

  3.   

    目前,您只能在模式中使用(?J)PCRE_INFO_JCHANGED。   我以前曾向维护者提出建议,但不接受   将“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);
    

    http://3v4l.org/fnm76#v446