2010-01-06 67 views
7

我需要將字符串拆分爲Ruby中的部分列表,但我需要忽略對象內的東西。例如:在Ruby中拆分字符串,忽略括號內容?

A +4, B +6, C (hello, goodbye) +5, D +3 

我想結果列表是:

[0]A +4 
[1]B +6 
[2]C (hello, goodbye) +5 
[3]D +3 

但我不能簡單地拆分的逗號,因爲那樣會分裂括號中的內容。有沒有辦法在沒有將大括號中的逗號解析爲其他東西的情況下將其分割出來?

謝謝。

+0

frowny面孔謹防:-(搞亂了解析 – 2010-01-06 20:19:36

回答

13

試試這個:

s = 'A +4, B +6, C (hello, goodbye) +5, D +3' 
tokens = s.scan(/(?:\(.*?\)|[^,])+/) 
tokens.each {|t| puts t.strip} 

輸出:

A +4 
B +6 
C (hello, goodbye) +5 
D +3 

的簡短解釋:

(?:  # open non-capturing group 1 
    \(  # match '(' 
    .*?  # reluctatly match zero or more character other than line breaks 
    \)  # match ')' 
    |  # OR 
    [^,]  # match something other than a comma 
)+   # close non-capturing group 1 and repeat it one or more times 

另一種選擇是各執一逗號緊跟一些空格,只有當第一在展望時可以看到的括號是一個開括號(或根本沒有括號):即。該字符串的結尾):

s = 'A +4, B +6, C (hello, goodbye) +5, D +3' 
tokens = s.split(/,\s*(?=[^()]*(?:\(|$))/) 
tokens.each {|t| puts t} 

會產生相同的輸出,但是我覺得scan方法清潔。

+0

#=> [ 「+4」, 「B + 6」,「C(!你好,再見)+5「,」D +3「] 對我來說看起來很完美可能想要#trim它去除周圍的空白 – 2010-01-06 20:24:00

+0

:)已經看到了空格並添加了'trim' – 2010-01-06 20:30:36

+0

很好的答案,謝謝: ) – Colen 2010-01-06 20:52:11

5
string = "A +4, B +6, C (hello, goodbye) +5, D +3" 
string.split(/ *, *(?=[^\)]*?(?:\(|$))/) 
# => ["A +4", "B +6", "C (hello, goodbye) +5", "D +3"] 

如何這個表達式的工作原理:

/ 
    *, *  # find comma, ignoring leading and trailing spaces. 
    (?=   # (Pattern in here is matched against but is not returned as part of the match.) 
    [^\)]*? # optionally, find a sequence of zero or more characters that are not ')' 
    (?:  # <non-capturing parentheses group> 
     \(  #  left paren ')' 
     |  #  - OR - 
     $  #  (end of string) 
    ) 
) 
/
+0

這可能有點神祕,沒有一個解釋,可能是膽小鬼正在發狂的愛好者! :)。但是,一個很好的解決方案。 – 2010-01-06 20:38:54

+0

這是如何工作的?我找不到任何關於正則表達式如何與分割一起工作的良好文檔 - 比如Bart K.說我對於正則表達式 – Colen 2010-01-06 20:53:08

+0

@Colen並不是很好,我發佈了一個非常類似的正則表達式作爲第二個解決方案,其中包括一個解釋。 – 2010-01-06 20:54:04

相關問題