【问题标题】:Split string in Ruby, ignoring contents of parentheses?在Ruby中拆分字符串,忽略括号的内容?
【发布时间】:2010-01-06 20:05:48
【问题描述】:

我需要将字符串拆分为 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

但我不能简单地用逗号分开,因为那会分开括号的内容。有没有办法在不将大括号中的逗号预先解析为其他内容的情况下拆分内容?

谢谢。

【问题讨论】:

  • 提防皱眉脸 :-( 搞砸解析!

标签: ruby string split


【解决方案1】:

试试这个:

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 方法更干净。

【讨论】:

  • # => ["A +4", "B +6", "C (hello, goodbye) +5", "D +3"] 对我来说看起来很完美。可能想要#trim 以删除周围的空白。
  • 这不适用于A +4, B +6, C (hello, (how are you?, bad)goodbye) +5, D +3。知道如何解决它吗?
  • @rochb,当任意数量的嵌套括号起作用时,请使用适当的解析器,不要使用正则表达式进行破解。
【解决方案2】:
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)
    )
  )
/

【讨论】:

  • 如果不解释 OP 可能是胆小的正则表达式爱好者,这可能有点神秘! :)。但仍然是一个很好的解决方案。
  • 这是如何工作的?我找不到任何关于正则表达式如何与拆分一起工作的好的文档 - 就像 Bart K. 说我对正则表达式不太擅长
  • @Colen,我发布了一个非常相似的正则表达式作为第二个解决方案,包括解释。
猜你喜欢
  • 1970-01-01
  • 2018-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-22
  • 1970-01-01
  • 2015-08-08
相关资源
最近更新 更多