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

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

Следующие:

$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]);

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

2 ответа

Решение

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

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

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

preg_replace_callback($pattern, function($match) use (&$matches) {
    $matches[$match[1]] = $match[2];
}, $data);
Другие вопросы по тегам