分裂的正则表达式模式

我想解决这个问题。

  • ,逗号:拆分条款
  • "双引号:字符串值(忽略特殊字符)
  • []数组

例如:

输入: a=1,b="1,2,3",c=[d=1,e="1,2,3"]

预期产量:

  a=1 b="1,2,3" c=[d=1,e="1,2,3"] 

但我无法超越结果。

我写了下面的代码:

  String line = "a=1,b=\"1,2,3\",c=[d=1,e=\"1,11\"]"; String[] tokens = line.split(",(?=(([^\"]*\"){2})*[^\"]*$)"); for (String t : tokens) System.out.println("> " + t); 

我的输出是:

 a=1 b="1,2,3" c=[d=1 e="1,11"] 

我需要更改什么才能获得预期的输出? 我应该坚持正则表达式还是其他解决方案更灵活,更容易维护?

这个正则表达式的作用是:

 ",(?=(([^\"]*\"){2})*[^\"]*$)(?=([^\\[]*?\\[[^\\]]*\\][^\\[\\]]*?)*$)" 

它的工作原理是在逗号后面添加一对前导以匹配方括号对 – 如果你在方括号内的术语中,当然你不会有平衡括号跟随。

这是一些测试代码:

 String line = "a=1,b=\"1,2,3\",c=[d=1,e=\"1,11\"]"; String[] tokens = line.split(",(?=(([^\"]*\"){2})*[^\"]*$)(?=([^\\[]*?\\[[^\\]]*\\][^\\[\\]]*?)*$)"); for (String t : tokens) System.out.println(t); 

输出:

 a=1 b="1,2,3" c=[d=1,e="1,11"] 

我知道这个问题差不多有一年了,但是……这个正则表达式要简单得多:

 \[[^]]*\]|"[^"]*"|(,) 
  • |的最左边的分支 匹配[complete brackets]
  • |的另一面 匹配\"strings like this\"
  • 右侧捕获第1组的逗号,我们知道它们是正确的逗号,因为它们与左侧的表达式不匹配
  • 我们需要做的就是分组第1组

拆分第1组捕获

您可以这样做(请参阅在线演示底部的输出):

 String subject = "a=1,b=\"1,2,3\",c=[d=1,e=\"1,11\"]"; Pattern regex = Pattern.compile("\\[[^]]*\\]|\".*?\"|(,)"); Matcher m = regex.matcher(subject); StringBuffer b= new StringBuffer(); while (m.find()) { if(m.group(1) != null) m.appendReplacement(b, "@@SplitHere@@"); else m.appendReplacement(b, m.group(0)); } m.appendTail(b); String replaced = b.toString(); String[] splits = replaced.split("@@SplitHere@@"); for (String split : splits) System.out.println(split); 

这是一个两步分裂:首先,我们用一些独特的东西替换逗号,例如@@SplitHere@@

优点和缺点

  • 这种技术的主要好处是它非常容易理解和维护。 如果你突然决定排除逗号{inside , curlies} ,你只需在正则表达式的左边添加另一个OR分支: {[^{}]*}
  • 熟悉它时,可以在很多情况下使用它
  • 在这种情况下,主要的缺点是我们在拆分之前进行两个步骤。 在我看来,与现代处理器无关。 可维护的代码更重要。

参考

该技术有许多应用。 这两个链接完全解释了这一点。

  • 如何匹配(或替换)模式除了情况s1,s2,s3 ……
  • 关于匹配模式的文章除非……