Я пытаюсь написать регулярное выражение, чтобы разбить строку на отдельные элементы внутри соответствующих фигурных скобок. Во-первых, он должен быть рекурсивным, а во-вторых, он должен возвращать смещения (как с 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}
и чтобы это было управляемым.
Любая помощь будет очень высоко ценится.
Вы можете использовать возможности регулярного выражения 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
)
)
Других решений пока нет …