ruby递归正则表达式

时间:2010-04-15 18:40:47

标签: ruby regex recursion

那为什么这不起作用?我正在创建一个匹配公式的正则表达式(这是更大的标准描述的一部分)。但我被困在这里,因为它似乎不想匹配公式中的嵌入式公式。

stat        = /(Stat3|Stat2|Stat1)/

number_sym  = /[0-9]*/
formula_sym = /((target's )?#{stat}|#{number_sym}|N#{number_sym})\%?/
math_sym    = /(\+|\-|\*|\/|\%)/

formula     = /^\((#{formula}|#{formula_sym})( #{math_sym} (#{formula}|#{formula_sym}))?\)$/

p "(target's Stat2 * N1%)".match(formula).to_s #matches
p "((target's Stat2 * N1%) + 3)".match(formula).to_s #no match
p "(Stat1 + ((target's Stat2 * N1%) + 3))".match(formula).to_s #no match

3 个答案:

答案 0 :(得分:7)

当您使用#{ }语法时,Ruby会使用to_s将Regexp对象转换为字符串。看看将Regexp对象转换为字符串时会发生什么:

irb> re = /blah/
  => /blah/
irb> re.to_s
  => "(?-mix:blah)"
irb> "my regex: #{re}"
  => "my regex: (?-mix:blah)"
irb> /my regex: #{re}/
  => /my regex: (?-mix:blah)/

要获取所需的字符串(在我的示例中为“blah”),请使用Regexp#source方法:

irb> re.source
"blah"

所以使用你的例子:

formula_sym = /((target's )?#{stat.source}|#{number_sym.source}|N#{number_sym.source})\%?/

答案 1 :(得分:3)

/(
  (?<non_grouping_char>
    [^\(\{\[\<\)\}\]\>]
  ){0}
  (?<parens_group>
    \( \g<content> \)
  ){0}
  (?<brackets_group>
    \[ \g<content> \]
  ){0}
  (?<chevrons_group>
    \< \g<content> \>
  ){0}
  (?<braces_group>
    \{ \g<content> \}
  ){0}
  (?<balanced_group>
    (?>
      \g<parens_group>   |
      \g<brackets_group> |
      \g<chevrons_group> |
      \g<braces_group>
    )
  ){0}
  (?<content>
    (?> \g<balanced_group> | \g<non_grouping_char> )*
  ){0}
  \A \g<content> \Z
)/uix

如果这可以帮助你,那就喝我吧。适合我。适用于任何允许命名组的regexp引擎。它将验证任何没有任何组或嵌套字符组的内容到任何深度。

答案 2 :(得分:1)

您不能使用这样的递归:#{formula}定义中的formula被转换为空字符串。你想要的是超出正则表达式的能力 - 正则表达式甚至不能匹配嵌套括号。我怀疑你需要一个真正的解析器来做你想做的事情。例如,请查看treetop

相关问题