2010-01-06 69 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

相关问题