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

时间:2013-08-24 23:49:20

标签: ruby regex

我想用逗号分隔字符串:

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

如果子字符串用括号括起来,我不想拆分子字符串:

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

应该产生:

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

有什么建议吗?

2 个答案:

答案 0 :(得分:11)

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

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']

答案 1 :(得分:3)

假设括号不是嵌套的:

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