PHP регулярное выражение для поиска "функций" в строке
Есть строка типа строка с {@rand(1||{@rand(2|3|{@rand(4|5)})})} и {@rand(1|{@rand(2|3|{@rand(4|5)})})}. Здесь {@rand(param1|param2|)} - вызов функции rand с параметрами(param1, param2 и ПУСТАЯ СТРОКА).
В качестве параметров может быть строка, пустая строка или вызов другой подобной функции.
И в этой строке мне нужно найти все вызовы функций ПЕРВОГО УРОВНЯ. Т.е. здесь результат такой
<?php
array(
'{@rand(1||{@rand(2|3|{@rand(4|5)})})}',
'{@rand(1|{@rand(2|3|{@rand(4|5)})})}'
);
Я составил такую регулярку - /{@(?<func>\w+?)\((?<params>.*)\)}/ui (Она работает неправильно)
Но здесь проблема в том, регулярка не видит конец первой функции и захватывает всё от начала первой и конца второй функций
Помогите составить регулярное выражение)
Ответы (1 шт):
Вы можете использовать
{@(?<func>\w+)(\((?<params>(?:[^()]++|(?2))*)\))}
См. пример работы выражения. Подробности:
{@- текст{@(?<func>\w+)- Подмаска "func" (кроме того, это подмаска №1): одна и более букв, цифр или знаков подчёркивания(\((?<params>(?:[^()]++|(?2))*)\))- Подмаска №2:\(- символ((?<params>(?:[^()]++|(?2))*)- Подмаска "params": один и более символов, отличных от(и), или рекурсивный повтор второй подмаски\)- символ)
}- символ}
См. пример кода на PHP:
$re = '/{@(?<func>\w+)(\((?<params>(?:[^()]++|(?2))*)\))}/u';
$str = 'строка с {@rand(1||{@rand(2|3|{@rand(4|5)})})} и {@rand(1|{@rand(2|3|{@rand(4|5)})})}.';
if (preg_match_all($re, $str, $matches, 0, PREG_SET_ORDER)) {
print_r($matches["func"]);
print_r($matches["params"]);
}
Результат:
Array
(
[0] => rand
[1] => rand
)
Array
(
[0] => 1||{@rand(2|3|{@rand(4|5)})}
[1] => 1|{@rand(2|3|{@rand(4|5)})}
)