ruby рекурсивное регулярное выражение - PullRequest
6 голосов
/ 15 апреля 2010

Так почему же это не работает? Я создаю регулярное выражение, которое будет соответствовать формуле (которая затем является частью более крупного стандартного описания). Но я застрял здесь, поскольку не похоже, чтобы он соответствовал встроенным формулам в формуле.

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 ]

7 голосов
/ 15 апреля 2010

Когда вы используете синтаксис #{ }, 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})\%?/
3 голосов
/ 06 июля 2012
/(
  (?<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

Пей мне, если это тебе поможет. Работает для меня. Работает в любом движке регулярных выражений, который позволяет именованные группы. Он будет проверять любой контент, который не имеет ни групп, ни групп вложенных символов, на любую глубину.

1 голос
/ 15 апреля 2010

Вы не можете использовать рекурсию таким образом: #{formula} s в вашем определении formula конвертируются в пустые строки. То, что вы хотите, находится за пределами возможностей регулярного выражения - регулярные выражения не могут даже соответствовать вложенным скобкам. Я подозреваю, что вам понадобится настоящий парсер, чтобы делать то, что вы хотите. Проверьте Верх дерева , например.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...