Использовать предыдущую обратную ссылку как имя именованной группы захвата

Есть ли способ использовать обратную ссылку на предыдущую группу захвата в качестве имени именованная группа захвата? Это может быть невозможно, если нет, то это правильный ответ.

Следующие:

$data = 'description: some description';
preg_match("/([^:]+): (.*)/", $data, $matches);
print_r($matches);

Урожайность:

(
[0] => description: some description
[1] => description
[2] => some description
)

Моя попытка использовать обратную ссылку на первую группу захвата в качестве именованной группы захвата (?<$1>.*) говорит мне, что это либо невозможно, либо я просто делаю это неправильно:

preg_match("/([^:]+): (?<$1>.*)/", $data, $matches);

Урожайность:

Предупреждение: preg_match (): ошибка компиляции: нераспознанный символ после (?< по смещению 12

Желаемый результат будет:

(
[0] => description: some description
[1] => description
[description] => some description
)

Это упрощается с помощью preg_match, Когда используешь preg_match_all Я обычно использую:

$matches = array_combine($matches[1], $matches[2]);

Но подумал, что я мог бы быть более ловким, чем это.

5

Решение

Короче говоря, это невозможно, вы можете придерживаться средств программирования, которые вы использовали до сих пор.

Имена групп (которые должны состоят из 32 буквенно-цифровых символов и символов подчеркивания, но должны начинаться с нецифровой цифры) анализируются во время компиляции, а значение обратной ссылки известно только во время выполнения. Обратите внимание, что это также причина, по которой вы не можете использовать обратную ссылку внутри вид сзади (хотя вы ясно видите, что /(x)y[a-z](?<!\1)/ все в порядке, PCRE regex engine видит иначе так как он не может определить длину взгляда с обратной ссылкой).

4

Другие решения

У вас уже есть ответ на вопрос о регулярных выражениях (нет), но для другого подхода на основе PHP вы можете попробовать использовать обратный вызов.

preg_replace_callback($pattern, function($match) use (&$matches) {
$matches[$match[1]] = $match[2];
}, $data);
2