2009-05-26 32 views
1

如何,使用正则表达式,这字符串分裂:分割一个复杂的字符串使用正则表达式

string = "a[a=d b&c[e[100&2=34]]] e[cheese=blue and white] x[a=a b]" 

这个阵列

string.split(regexp) => 

[ "a[a=d b&c[e[100&2=34]]]", "e[cheese=blue and white]", "x[a=a b]" ] 

的基本规则是字符串应拆分为空格(\ s),除非空格存在于括号([]);

回答

4

如果规则很简单,我会建议只是手动做。逐步浏览每个角色,并通过每个角色增加1来追踪你的嵌套等级[并且每个角色降低1]。如果您使用嵌套== 0到达空间,则分割。

编辑: 我在想,我可能还会提到在某些语言中还有其他模式匹配工具可以在本质上支持这类事情。例如,在Lua中,您可以使用'%b []'来匹配平衡的嵌套[]'。 (当然,Lua没有内置的分割功能....)

+0

+1 - 好主意!回到基础,哟! – nickf 2009-05-26 15:02:44

5

你不能;正则表达式基于没有“堆栈”的状态机,因此您可以记住嵌套层次的数量。

但也许你可以使用一个技巧:尝试将字符串转换为有效的JSON string。然后,您可以使用eval()将其解析为JavaScript对象。

0

你能分割吗?(?< =])\ s(?= [a-z] [)“?也就是前面有空格],后面跟着一个字母和一个[?这假定你从来没有像“a [b = d [x = y b] g [w = v b]]这样的括号内的任何字符串”

0

另一种是循环方法,一次只拆分一个级别的嵌套括号,否则很难确保您的单个正则表达式将按预期工作。

下面是红宝石一个例子:

str = "a[a=d b&c[e[100&2=34]]] e[cheese=blue and white] x[a=a b]" 
left = str.dup 
tokn=0 
toks=[] 
# Deconstruct 
loop do 
    left.sub!(/\[[^\]\[]*\]/,"\{#{tokn}\}") 
    break if $~.nil? 
    toks[tokn]=$& 
    tokn+=1 
end 
left=left.split(/\s+/) 
# Reconstruct 
(toks.size-1).downto(0) do |tokn| 
    left.each { |str| str.sub!("\{#{tokn}\}", toks[tokn]) } 
end 

上述用途{N},其中n是解构期间的整数,因此在一些情况下,串中这样原始输入会打破重建。这应该说明方法。

虽然通过遍历字符来完成拆分的代码编写更简单,更安全。

实例红宝石:

str = "a[a=d b&c[e[100&2=34]]] e[cheese=blue and white] x[a=a b]" 
toks=[] 
level=st=en=0; 
str.each_byte do |c| 
    en+=1; 
    level+=1 if c=='['[0]; 
    level-=1 if c==']'[0]; 
    if level==0 && c==' '[0] 
    toks.push(str[st,en-1-st]); 
    st=en 
    end 
end  
toks.push(str[st,en-st]) if st!=en 
p toks 
相关问题