分裂的正则表达式模式
我想解决这个问题。
-
,
逗号:拆分条款 -
"
双引号:字符串值(忽略特殊字符) -
[]
数组
例如:
输入: 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 ……
- 关于匹配模式的文章除非……