2015-05-26 57 views
2

我目前正在研究一個ruby程序來計算術語。除了一件事情之外,它工作得很好:括號。我需要過濾內容或至少將內容放入數組中,但我已嘗試了一個小時以提出解決方案。這裏是我的代碼:分割括號內容而不分開括號ruby

splitted = term.split(/\(+|\)+/) 

我需要一個數組,而不是括號,例如:

"1-(2+3)" #=>["1", "-", ["2", "+", "3"]] 

我已經嘗試過這樣的:

/(\((?<=.*)\))/ 

但它返回:

Invalid pattern in look-behind. 

有人可以幫我t他?

UPDATE

我忘了提,我的程序會分裂術語,我只需要括號的內容是一個數組。

+0

我覺得stringscanner更適合這類任務。 –

+0

無效的消息似乎是因爲在大多數引擎中(除了Dot-Net),lookbehinds不能具有可變長度。另一件事是,如果你試圖獨立解析'(2 + 3)',除非Ruby支持遞歸,否則你不能這麼做。而且,我不知道它是否。另一種方法是自己解析它,逐個字符地跟蹤堆棧的嵌套。 – sln

+0

這將是一個適當的嵌套示例:'(5-(3 * 2(4 + 1)-9)+7)* 4' – sln

回答

0

如果您需要跟蹤數組括號的層次結構,您將不會僅僅使用正則表達式來管理它。您需要逐字解析字符串,並保留一堆表達式。

僞代碼:

  • 表達式=新的堆棧
  • 上堆添加新的數組
  • 而字在字符串:
    • 如果單詞是 「(」:添加新的陣列上層疊
    • 否則如果單詞是「)」:從堆棧中刪除最後一個數組並將其添加到堆棧的(下一個)最後一個數組
    • 否則:單詞添加到堆棧
  • 當退出循環的最後一個數組,應該只有一個堆疊陣列(如果沒有,你有不一致的開/關括號)。

注意:如果您的最終目標是評估表達式,您可以節省時間並在Postfix中解析字符串(又名Reverse-Polish Notation)。 另請考慮使用off-the-shelf libraries

0

解決方案取決於您期望的括號之間的模式,您尚未指定。 (例如,對於"(st12uv)",您可能需要["st", "12", "uv"],["st12", "uv"],["st1", "2uv"]等)。如果,在你的榜樣,它是一個自然數後跟一個+,緊接着又自然數,你可以這樣做:

str = "1-(2+ 3)" 

r =/
    \(\s* # match a left parenthesis followed by >= 0 whitespace chars 
    (\d+) # match one or more digits in a capture group 
    \s* # match >= 0 whitespace chars 
    (\+) # match a plus sign in a capture group 
    \s* # match >= 0 whitespace chars 
    (\d+) # match one or more digits in a capture group 
    \s* # match >= 0 whitespace chars 
    \)  # match a right parenthesis 
    /x 

str.scan(r0).first 
    => ["2", "+", "3"] 

假設,而不是+可能是+-*/。然後,你可以更改:

(\+) 

到:

([-+*\/]) 

需要注意的是,在一個字符類,+不需要進行轉義,如果它是第一個或最後一個字符-不需要進行轉義(在這種情況下,它不代表範圍)。

順便提一下,您收到錯誤消息「無效的後向模式」,因爲Ruby的週期不能包含可變長度匹配(即.*)。通過使用\K來代替積極向後看,你可以解決這個問題。例如,

r =/
    \d+ # match one or more digits 
    \K # forget everything previously matched 
    [a-z]+ # match one or more lowercase letters 
    /x 

"123abc"[r] #=> "abc" 
相關問題