2017-02-26 69 views
0

我想用冒号拆分一个字符串。使用正则表达式通过冒号拆分一个Ruby字符串(除了括号内部)

这是输入的一个示例:

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>(.*)$
  • 比赛必须是唯一的,有三组。

你能给我一个建议吗?

+0

所以,第一个约束意味着'一个:二:三:four'应该产生不匹配,对不对? –

+0

谢谢卡里。刚刚编辑。 – BnG

+0

Wiktor此输入str =“one:two:three:four”必须产生此输出数组= [“one”,“two”,“three”,“four”],但使用此模板^(。+)(。 *。)(。*)(。*)$ – BnG

回答

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]"] 
+0

谢谢。不幸的是我需要正则表达式的解决方案,因为我将在Puppet模块的title_patterns方法中使用ruby正则表达式(只接受正则表达式)。 – BnG

+0

我修改了我的答案,给你我相信你需要的东西,虽然有点啰嗦,有时你会做你应该做的。 –

+0

我不知道Puppet(或Rails一般),所以我假设字符串和正则表达式都传递给Puppet可能是不正确的。 –

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] 
+0

...呃...好的。有用。但是我不能调用map方法(由Puppet title_patterns方法施加的限制)并解析任何sting。相反,你的输入应该被正则表达式解析,如^(。+)(。*)(。*)$ – BnG

+0

@BnG:没有递归,纯粹不可能使用正则表达式。 – dawg

相关问题