2010-04-15 72 views
6

那麼爲什麼這不起作用?我正在創建一個匹配公式的正則表達式(這是一個更大的標準描述的一部分)。但是我被困在這裏,因爲它似乎不想匹配公式中的嵌入式公式。ruby​​遞歸正則表達式

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 

回答

7

當您使用#{ }語法,紅寶石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定義#{formula} s的轉換爲空字符串:

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

謝謝......我確實發現它爲什麼不能正常工作......我猜應該把我的問題解釋爲「我怎樣才能得到它」......看起來像#{formula.source}顯示公式仍然是零。 – 2010-04-15 18:53:19

1

不能使用遞歸這樣。你想要的不是正則表達式的能力 - 正則表達式甚至不能匹配嵌套的括號。我懷疑你需要一個真正的解析器來做你想做的事情。例如,請查看treetop

+0

優秀... treetop將允許我輕鬆地將我當前的定義規範遷移到它。謝謝! – 2010-04-15 19:12:46

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 

啤酒我,如果這可以幫助你。適用於我。適用於允許命名組的任何正則表達式引擎。它將驗證任何沒有組或嵌套字符組的任何內容到任何深度。

+1

如果我們見面,我肯定會給你一杯啤酒。你最喜歡什麼味道? :)從那時起,我投票了! – Stephan 2012-10-11 08:42:52