PHP / Regex:捕获重复命名递归的所有匹配项

时间:2018-04-11 12:34:41

标签: php regex pcre regex-group

我有以下正则表达式:

\(                                          (?# 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]匹配。

请参阅演示here

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。

规则:

  • 每个表达式都是一个函数调用,它包含函数名,括号,至少一个参数和可选的Function标志:
  • func([param]) - 一个参数
  • func([param1], [param1]) - 两个参数,params之间的空格被忽略。
  • 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 个答案:

没有答案