PHP / Regex: захват всех совпадений для повторяющейся именованной рекурсии

У меня есть следующее регулярное выражение:

\(                                          (?# Expression start)
(?<optgroup_start>\()                  (?# Parameter group start)
(?<parameter_set>(?:\[(?:[a-z0-9]+)\],*\s*)+) (?# Parameters, subject to recursion)
(?<optgroup_end>\))                                (?# Parameter group end)
,*\s*
(?:                                  (?# Options group start)
"(?<options_scalar>.*)"      (?# String options)
|                                  (?# OR other)
(?<options_complex>.*)
)                                    (?# Options group end)
|                                    (?# OR simple structures)
(?<simple_parameter_set>(?:(?&parameter_set)+)) (?# <----------- WRONG!!!)
\) (?# Expression end)

Тестовые строки:

НЕ РАБОТАЕТ:

or_x(equal([attr1], 1), in_array(explode([keywords]), "hello")) // There should be 2 matches: [attr1] and [keywords]

ХОРОШО РАБОТАТЬ:

explode([Rooms])
implode(([attr1],[attr2]), ",")
implode(([attr1],[attr2]))
equal([attr1],[attr2])
implode(([attr1],[attr2]), {"sensitive":true,"nullable":false})

Работает хорошо, кроме последнего правила — фиксирует только последнее вхождение. Я пробовал рекурсию с (?R), но это не с бесконечным циклом.

Так что проблема, которую я считаю только в той строке, которую я обозначил как WRONG, Остальное фиксирует все остальные тестовые строки без каких-либо проблем.

Я ожидаю иметь [attr1] а также [keywords] соответствует.

Посмотреть демо Вот.

UPD 1. я использую preg_replace_callback подставить реальные значения, поэтому все, что я делаю здесь, это просто выборка [somevar] данные в массив (и делать некоторые другие захваты) и заменить его на то, что мне нужно. Увидеть ниже.

UPD 2.

Случай 1:

or_x(equal([attr1], 1), in_array(explode([keywords]), "hello"))

будет преобразован в

or_x(equal($attr1, 1), in_array(explode($keywords), "hello"))

Случай 2:

implode(([attr1],[attr2]), ",")

будет преобразован в

implode([$attr1,$attr2], ",")

Случай 3:

implode(([attr1],[attr2]), {"sensitive":true,"nullable":false})

будет преобразован в

implode([$attr1,$attr2], '{"sensitive":true,"nullable":false}')

UPD 3.

Правила:

  • каждое выражение — это вызов функции, который содержит имя функции, круглые скобки, хотя бы один параметр и необязательные флаги функции:
  • func([param]) — один параметр
  • func([param1], [param1]) — два параметра, пробел между параметрами игнорируется.
  • func(([param1], [param1]), "some_flag") — если указан флаг, то набор параметров должен быть заключен в дополнительные скобки.
  • func(([param1], [param1]), {"flag1": true, "flag2": "test", "flag2": 123}) — флаги могут быть указаны как JSON.
  • все матчи [pattern] должен стать $ pattern
  • func(([param1], func([param1]) — поддерживается любой уровень вложенности
  • func(([param1], func(([param1], [param1]), "some_flag") — Вложение поддерживается с поддержкой всех правил выше

0

Решение

Задача ещё не решена.

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

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

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