如何在php中使用J修饰符? [英] How to use J modifier in php?

查看:34
本文介绍了如何在php中使用J修饰符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

来自 php 文档

J (PCRE_INFO_JCHANGED)(?J) 内部选项设置更改本地 PCRE_DUPNAMES 选项.允许子模式的重复名称.

所以 J 修饰符允许命名捕获组中的重复名称.在这个演示中查看右侧的匹配信息.

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

PHP 警告:preg_match_all():未知修饰符J"

这是我的代码,

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

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

'~(?J)(?foo).*?(?buz)~'

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

输出:

数组([0] =>大批([0] =>富巴巴兹)[名称] =>大批([0] =>嗡嗡声)[1] =>大批([0] =>富)[2] =>大批([0] =>嗡嗡声))

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

数组([0] =>嗡嗡声)

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

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

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

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

解决方案

  1. 因为数组不能包含两个相等的键.这就是为什么 'name' 键排在最前面,但具有最后一个值(已重新分配)的原因.

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

<块引用>

目前您只能在模式中使用 PCRE_INFO_JCHANGED by (?J).我曾多次向维护者建议过,但它没有接受'J' 作为扩展中的有效修饰符.

此修饰符的使用示例

preg_match_all('/(?J)(?.*)1|(?.*)2|(?.*)3$/',"text2\npext3", $matches, PREG_SET_ORDER);var_dump($matches);preg_match_all('/(?J)(?.*)1|(?.*)2|(?.*)3$/', "text2\npext3",$匹配);var_dump($matches);

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

From the php docs

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

So J modifer allows duplicate names in the named captruing groups. See the match information at the right side in this demo.

When i'm trying to check this modifier in php, it displays the below warning and it won't display any output.

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

Here is my code,

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

Then i able to solve this problem by adding the J modifier in the regex itself like,

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

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

Output:

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

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

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

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

)

did you see that the name is an index for only the second group not the first group. But we define both under a single name. In this it clearly shows that there are two different groups with same name called name. But in php, print_r($match['name']); prints only the second group

Array
(
    [0] => buz
)

But not the first one. Why? I assumed that if we do print_r($match['name']);, it would display the both but not the first.

So my two questions regarding the use of J modifier in PHP are,

  1. Why it refer the second group instead of both? If it always refers to the last group then what's the need for duplicate names in the capturing groups?

  2. And also why adding the J modifier after the php delimiters displays warning (not working)?

解决方案

  1. Because array could not contains two equal keys. That's why 'name' key comes first, but has the last value (it was reassigned).

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

Currently you can only use PCRE_INFO_JCHANGED by (?J) in the pattern. I have suggested times ago to the maintainer, but it wasn't accept the addiction of 'J' as valid modifier in the extension.

Example of usage this modifier

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

这篇关于如何在php中使用J修饰符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆