在Ruby中拆分字符串,忽略括号内容?

Col*_*len 7 ruby string split

我需要将一个字符串拆分成Ruby中的部分列表,但我需要忽略paramentheses中的内容.例如:

A +4, B +6, C (hello, goodbye) +5, D +3
Run Code Online (Sandbox Code Playgroud)

我希望结果列表是:

[0]A +4
[1]B +6
[2]C (hello, goodbye) +5
[3]D +3
Run Code Online (Sandbox Code Playgroud)

但我不能简单地用逗号分割,因为这会分割括号的内容.有没有办法在没有预先解析括号中的逗号的情况下拆分东西?

谢谢.

Bar*_*ers 13

试试这个:

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

输出:

A +4
B +6
C (hello, goodbye) +5
D +3
Run Code Online (Sandbox Code Playgroud)

一个简短的解释:

(?:        # 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
Run Code Online (Sandbox Code Playgroud)

另一种选择是只有在向前看时可以看到的第一个括号是一个左括号(或者根本没有括号:即字符串的结尾)时,在逗号之后分隔一些空格:

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

将产生相同的输出,但我发现scan方法更清洁.


gab*_*iel 5

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

这个正则表达式如何工作:

/
   *, *        # 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)
    )
  )
/
Run Code Online (Sandbox Code Playgroud)