除了括号内,如何使用正则表达式用逗号分隔字符串?

我想用逗号分割一个字符串:

"a,s".split ',' # => ['a', 's'] 

如果它被括号括起来,我不想分割子字符串:

 "a,s(d,f),g,h" 

应该产量:

 ['a', 's(d,f)', 'g', 'h'] 

有什么建议吗?

要处理嵌套的括号,您可以使用:

 txt = "a,s(d,f(4,5)),g,h" pattern = Regexp.new('((?:[^,(]+|(\((?>[^()]+|\g<-1>)*\)))+)') puts txt.scan(pattern).map &:first 

图案细节:

 ( # first capturing group (?: # open a non capturing group [^,(]+ # all characters except , and ( | # or ( # open the second capturing group \( # ( (?> # open an atomic group [^()]+ # all characters except parenthesis | # OR \g<-1> # the last capturing group (you can also write \g<2>) )* # close the atomic group \) # ) ) # close the second capturing group )+ # close the non-capturing group and repeat it ) # close the first capturing group 

第二个捕获组描述嵌套的括号,它可以包含不是括号的字符或捕获组本身。 这是一种递归模式。

在模式内部,您可以引用具有其编号的捕获组(第二个捕获组的\g<2> )或其相对位置( \g<-1>模式中当前位置左侧的第一个位置) (如果使用命名捕获组,则使用他的名字)

注意:如果在非捕获组结束之前添加|[()] ,则可以允许单括号。 那么a,b(,c会给你['a', 'b(', 'c']

假设括号不是嵌套的:

 "a,s(d,f),g,h" .scan(/(?:\([^()]*\)|[^,])+/) # => ["a", "s(d,f)", "g", "h"]