2017-02-26 29 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

相關問題