没有编号数组的PHP子模式

将preg_match与子模式一起使用时,始终返回具有相同数据的双键数组,一个具有子模式名称,另一个使用数字标记.因为我匹配成千上万行每行几千字节,我担心数字数组会占用额外的内存.有没有正确的方法来禁用数字标签数组返回?

例:

<?PHP

header('Content-Type: text/plain');

$data = <<<START
I go to school.
He goes to funeral.
START;
preg_match_all('@^(?<who>.*?) go(es)* to (?<place>.*?)$@m',$data,$matches);
print_r($matches);

?>

输出

Array
(
    [0] => Array
        (
            [0] => I go to school.
            [1] => He goes to funeral.
        )

    [who] => Array
        (
            [0] => I
            [1] => He
        )

    [1] => Array
        (
            [0] => I
            [1] => He
        )

    [2] => Array
        (
            [0] => 
            [1] => es
        )

    [place] => Array
        (
            [0] => school.
            [1] => funeral.
        )

    [3] => Array
        (
            [0] => school.
            [1] => funeral.
        )

)

解决方法

php.net- Subpatterns

It is possible to name a subpattern using the Syntax (?P<name>pattern). This subpattern will then be indexed in the matches array by its normal numeric position and also by name.

我看不到只按名称给出索引的选项.

所以,我认为,如果你不想要这个数据两次,唯一的可能是:不要使用命名组.

这真的是一个问题吗? IMO只有在遇到问题时才会对此进行优化,因为这会占用额外的内存!提高可读性应该值得记忆!

更新

看起来像go(es)*应该只匹配一个可选的“es”.在这里,您可以使用非捕获组来节省内存.

preg_match_all('@^(?<who>.*?) go(?:es)? to (?<place>.*?)$@m',$matches);

通过以?开始组:不存储匹配的内容.我还替换了*表示0或更多,并且还将匹配“goeseses”与?这意味着0或1.

相关文章

统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
前言 之前做了微信登录,所以总结一下微信授权登录并获取用户...
FastAdmin是我第一个接触的后台管理系统框架。FastAdmin是一...
之前公司需要一个内部的通讯软件,就叫我做一个。通讯软件嘛...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...