使用正则表达式按冒号(括号内除外)拆分Ruby字符串

时间:2017-02-26 23:26:19

标签: ruby regex

我想用冒号分割字符串。

这是输入的一个例子:

str = "one[two:[three::four][five::six]]:seven:eight[nine:ten]"

这是输出的一个例子:

array = ["one[two:[three::four][five::six]]", "seven", "eight[nine:ten]"]

目标是了解正则表达式,表示括号内的冒号和嵌套括号

但是有一些限制因素:

  • 正则表达式的模板必须如下:^(.+)<colon_regex>(.*)<colon_regex>(.*)$
  • 匹配必须是唯一的,有三组。

你能给我一个建议吗?

2 个答案:

答案 0 :(得分:2)

你可以使用一个非常简单的正则表达式:

SUB_CHAR = 0.chr
  #=> "\x00"
r = /#{SUB_CHAR}/
  #=> /\x00/

将在s.split(r)中使用。

当然有一个问题:您必须修改传递给Puppet的字符串(以及上面的正则表达式)。

str = "one[two:[three::four][five::six]]:seven:eight[nine:ten]"

count = 0

idx = str.size.times.with_object([]) do |i,a|
  case str[i]
  when '[' then count += 1
  when ']' then count -= 1
  when ':' then a << i if count.zero?
  end
end
  #=> [33, 39]

s = str.dup
  #=> "one[two:[three::four][five::six]]:seven:eight[nine:ten]"
idx.each { |i| s[i] = SUB_CHAR }
s #=> "one[two:[three::four][five::six]]\u0000seven\u0000eight[nine:ten]"
s.split(r)
  #=> ["one[two:[three::four][five::six]]", "seven", "eight[nine:ten]"] 

答案 1 :(得分:1)

调整this嵌套括号正则表达式,您可以这样做:

txt="one[two:[three::four][five::six]]:seven:eight[nine:ten]" 
pat=Regexp.new('((?>[^:\[]+|(\[(?>[^\[\]]+|\g<-1>)*\]))+)')
puts txt.scan(pat).map &:first
one[two:[three::four][five::six]]
seven
eight[nine:ten]