正则表达式解析以逗号分隔的列表,不包括括号内的内容

时间:2015-10-28 20:02:49

标签: ruby regex

在Ruby中:

给出以下示例字符串:

str = 'foo,baz(some,other,stuff),hello,goodbye'

我想解析字符串,使得与parens一起出现的逗号不被视为分隔符。因此,在此示例中将捕获以下字段:

  1. FOO
  2. 巴兹(一些,其它,东西)
  3. 你好
  4. 再见
  5. 非常感谢!

2 个答案:

答案 0 :(得分:2)

使用正则表达式

[^,(]*(?:\([^)]*\))*[^,]*

<强> Mdnsjava

Regular expression visualization

答案 1 :(得分:1)

这是一个非正则表达式解决方案,它使用了Ruby很少使用的flip-flop operator

str = "foo,baz(some,other,stuff),hello,goodbye"

str.split(',').chunk { |s| s.include?('(') .. s.include?(')') ? true : false }.
               flat_map { |tf, a| tf ? a.join(' ') : a }
  #=> ["foo", "baz(some", "other", "stuff)", "hello", "goodbye"]

步骤:

arr = str.split(',')
  #=> ["foo", "baz(some", "other", "stuff)", "hello", "goodbye"] 

enum = arr.chunk { |s| s.include?('(') .. s.include?(')') ? true : false }
  #=> #<Enumerator: #<Enumerator::Generator:0x007fdf9d01d2e8>:each> 

除此之外:flip-flop运算符必须在if语句中,因此无法简化为:

enum = arr.chunk { |s| s.include?('(') .. s.include?(')') }

我们可以将此枚举器转换为数组,以查看它将传递给Enumerable#flat_map的值:

enum.to_a
  #=> [[false, ["foo"]], [true, ["baz(some", "other", "stuff)"]],
  #    [false, ["hello", "goodbye"]]] 

最后:

enum.flat_map { |tf, a| tf ? a.join(' ') : a }
  #=> ["foo", "baz(some", "other", "stuff)", "hello", "goodbye"]