来自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
修饰符的两个问题是,
为什么它引用第二组而不是两者?如果它总是引用最后一组,那么捕获组中重复名称的需要是什么?
还有为什么在php分隔符后显示警告(无法正常工作)后添加J
修饰符?
答案 0 :(得分:3)
因为数组不能包含两个相等的键。这就是为什么'name'键首先出现,但是有最后一个值(它被重新分配)。
目前,您只能在模式中使用(?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);