Итак, почему это не работает? Я создаю regex, который будет соответствовать формуле (который является затем частью большего стандартного описания). Но я застреваю здесь, поскольку это, кажется, не хочет соответствовать встроенным формулам в формуле.
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
Когда вы используете синтаксис # {}
, Ruby преобразует объект Regexp в строку, используя to_s
. Посмотрите, что происходит, когда вы конвертируете объект 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)/
Чтобы получить нужную строку (в моем примере «бла»), используйте метод Regexp # source
:
irb> re.source
"blah"
Итак, чтобы используйте ваш пример:
formula_sym = /((target's )?#{stat.source}|#{number_sym.source}|N#{number_sym.source})\%?/
Вы не можете использовать такую рекурсию: # {formula}
в вашем определении formula
преобразуются в пустые строки. То, что вы хотите, выходит за рамки возможностей регулярных выражений - регулярные выражения не могут соответствовать даже вложенным круглым скобкам. Я подозреваю, что вам понадобится настоящий парсер, чтобы делать то, что вы хотите. Посмотрите, например, верхушку дерева .