-6

我想解决这个问题。

  • , 逗号:拆分术语
  • " 双引号:字符串值(忽略特殊字符)
  • []大批

例如:

输入 :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"]

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

4

2 回答 2

52

这个正则表达式可以解决问题:

",(?=(([^\"]*\"){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"]
于 2013-08-01T05:47:23.083 回答
0

我知道这个问题已经将近一年了,但是......这个正则表达式要简单得多:

\[[^]]*\]|"[^"]*"|(,)
  • |比赛的最左边的分支[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分支:{[^{}]*}
  • 当您熟悉它时,您可以在许多情况下使用它
  • 在这种情况下,主要缺点是我们在拆分前进行替换时分两步进行。在我看来,与现代处理器无关。可维护的代码更为重要。

参考

这种技术有很多应用。在这两个链接中进行了充分的说明。

于 2014-06-19T03:31:48.630 回答