preg_match()中的动态捕获组名称

时间:2015-05-18 17:23:08

标签: php regex

在PHP中,是否可以创建动态命名的捕获组?

例如,我想将dsn解析为其组件。请考虑以下事项:

<?php

$dsn = 'mysql:host=localhost;dbname=mydatabase';

preg_match_all('/host=(?P<host>[^;]+);dbname=(?P<dbname>[^;]+)/', $dsn, $matches);

如果没有明确定义每个捕获组的名称,是否可以实现相同的结果?

换句话说,匹配模式/;|:([^=]+)=([^;]+)/并使用等号左侧的任何内容作为组的名称,以及右侧的任何内容作为值。

我知道我可以通过以下方式模仿所需的行为:

<?php

$dsn = 'mysql:host=localhost;dbname=mydatabase';

list($engine, $dsn) = explode(':', $dsn);
$result = [];

 while(preg_match('/;?(?P<key>[^=]+)=(?P<val>[^;]+)/', $dsn, $matches)) {
    $result[$matches['key']] = $matches['val'];
    $dsn = str_replace($matches[0], '', $dsn);
}

我也意识到还有其他几种方法可以实现这一目标。我不是在寻找一种解决方法,我有兴趣知道动态命名的捕获组是否可行,如果是,那怎么办?

2 个答案:

答案 0 :(得分:2)

不,命名捕获组不能是动态的。你所展示的几乎是实现预期结果的唯一途径。

答案 1 :(得分:1)

不,这是不可能的。

解决方法的想法:

$dsn = 'mysql:host=localhost;dbname=mydatabase';

if (preg_match_all('~([^;:=]+)=([^;]*)~', $dsn, $matches))
    $result = array_combine($matches[1], $matches[2]);