Schlaus
Schlaus

Reputation: 19212

Dynamic capture group name in preg_match()

In PHP, is it possible to create dynamically named capture groups?

For example say I want to parse a dsn into its components. Consider the following:

<?php

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

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

Is it possible to achieve the same result without explicitly defining each capture group's name?

In other words, match pattern /;|:([^=]+)=([^;]+)/ and use whatever is on the left side of the equals sign as the group's name, and whatever is on the right side as the value.

I am aware I could emulate the desired behavior with something like this:

<?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);
}

I'm also aware that there are several other ways of achieving this. I'm not looking for a workaround, I'm interested in knowing if dynamically named capture groups are possible, and if yes, how?

Upvotes: 0

Views: 306

Answers (2)

Casimir et Hippolyte
Casimir et Hippolyte

Reputation: 89547

No, it isn't possible.

idea of workaround:

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

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

Upvotes: 1

Amal Murali
Amal Murali

Reputation: 76646

No, named capture groups cannot be dynamic. What you've shown is pretty much the only way to achieve the desired result.

Upvotes: 2

Related Questions