Написание выражения для рекурсивного извлечения данных между круглыми скобками

Я пытаюсь написать регулярное выражение, чтобы разбить строку на отдельные элементы внутри соответствующих фигурных скобок. Во-первых, он должен быть рекурсивным, а во-вторых, он должен возвращать смещения (как с PREG_OFFSET_CAPTURE).

Я на самом деле думаю, что это, вероятно, менее эффективный способ обработки этих данных, но я не уверен в более простой и более управляемой техникой. (Если у вас есть, я хотел бы услышать это!)

Таким образом, вход может быть в следующем формате:

Hello {#name}! I'm a {%string|sentence|bit of {#random} text}

Обработка данных достаточно проста, если она находится в этот формат:

Hello {#name}! I'm a {%string|sentence|bit of random text}

Но это проблема рекурсивных фигурных скобок в другом наборе фигурных скобок, когда дело доходит до обработки.
Я использую следующий код для разделения строки:

preg_match_all("/(?<={)[^}]*(?=})/m", $string, $braces, PREG_OFFSET_CAPTURE);

И, как уже упоминалось, это очень хорошо для простой формы. Просто не так для более сложной формы. Намерение для этого (и у меня есть это функционал в нерекурсивной форме) состоит в том, чтобы заменить каждую заключенную в скобки область с содержанием, как обработано функциями, работая вверх.

В идеале я хотел бы иметь возможность написать Hello {#name}! I'm a {%string|sentence|bit of {?(random == "strange") ? {#random} : "strange"}} text} и чтобы это было управляемым.

Любая помощь будет очень высоко ценится.

5

Решение

Вы можете использовать возможности регулярного выражения PCRE для захвата групп в прогнозных и подпрограммах, чтобы получить вложенный {...} подстроки.

демо-версия regex доступна здесь.

$re = "#(?=(\{(?>[^{}]|(?1))*+\}))#";
$str = "Hello {#name}! I'm a {%string|sentence|bit of {#random} text}";
preg_match_all($re, $str, $matches, PREG_OFFSET_CAPTURE);
print_r($matches[1]);

Увидеть IDEONE демо

Он вернет массив с захваченными {…} -подобными строками и их позициями:

Array
(
[0] => Array
(
[0] => {#name}
[1] => 6
)

[1] => Array
(
[0] => {%string|sentence|bit of {#random} text}
[1] => 21
)

[2] => Array
(
[0] => {#random}
[1] => 46
)

)
2

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

Других решений пока нет …

По вопросам рекламы [email protected]