Java代码中的正则表达式帮助

时间:2012-12-07 03:13:07

标签: java regex

我需要一个正则表达式来解析一个字符串,需要用逗号分隔...用作分割的逗号只能匹配引号内的逗号...

should be 3: 3 (is right)
should be 3: 14 (is wrong, counted commas inside quotes)
should be 24: 12 (is wrong)
should be 24: 24. (is right)

对于以下结果测试用例:

String line ="com.day.image;uses:=\"javax.imageio.stream,javax.imageio.spi,javax.imageio.plugins.jpeg,org.slf4j,javax.imageio.metadata,javax.imageio,com.day.imageio.plugins,com.day.image.font\",com.day.imageio.plugins;uses:=\"javax.imageio,javax.imageio.metadata,javax.imageio.stream,javax.imageio.spi,org.w3c.dom\",com.day.image.font;uses:=\"com.day.image\"";

        String[] results1 = line.split("\",");
        String[] results2 = line.split(",");

        System.out.println("should be 3: "+ results1.length);
        System.out.println("should be 3: "+ results2.length);

        line = "com.day.cq.commons,com.day.cq.commons.inherit,com.day.cq.wcm.api,com.day.cq.wcm.api.components,com.day.cq.wcm.api.designer,com.day.cq.wcm.commons,com.day.cq.wcm.tags,com.day.cq.widget,javax.servlet,javax.servlet.http,javax.servlet.jsp;version=\"2.1\",javax.servlet.jsp.el;version=\"2.1\",javax.servlet.jsp.jstl.core,javax.servlet.jsp.jstl.fmt,javax.servlet.jsp.tagext;version=\"2.1\",org.apache.commons.lang;version=\"2.4\",org.apache.sling.api;version=\"2.1\",org.apache.sling.api.request;version=\"2.1\",org.apache.sling.api.resource;version=\"2.1\",org.apache.sling.api.scripting;version=\"2.1\",org.apache.sling.api.servlets;version=\"2.1\",org.apache.sling.scripting.jsp.taglib;version=\"2.0\",org.apache.sling.scripting.jsp.util;version=\"2.0\",org.slf4j;version=\"1.5\"";

        results1 = line.split("\",");
        results2 = line.split(",");

        System.out.println("should be 24: "+ results1.length);
        System.out.println("should be 24: "+ results2.length);

输出是,

should be 3: 3
should be 3: 14
should be 24: 12
should be 24: 24

已更新

我很清楚我需要什么,但我不知道该怎么做...我的解释是我想要完成的并不是最好的。一个定义不明确的问题,几乎不会导致解决方案。我的一个院系就是复杂的场景,显然今晚不适合我。

搜索后我再次提炼我的问题,谷歌搜索术语:“如何匹配引号之外的字符?”

现在很清楚谷歌的第一个结果应该是你最想要的,如果你问的是Google的正确问题;)。

第一次结果,Regex to pick commas outside of quotes

正则表达式为:(,)(?=(?:[^“'] | [”|'] [^“'] ”) $)。

测试和工作..

最后我假设编程技巧,理解技能之间存在差异,绝对不会被许多程序员带到那里..我在几个地方问过,而且大多数人说这是不可能的......显然它是

感谢您的时间,对不起,也许急于得到帮助。

这个网站很棒! :)

UPDATE2

此正则表达式(,)(?=(?:[^“'] | [”|'] [^“'] ”) $)。给我一个StackOverFlow的问题.. !!

at java.util.regex.Pattern$GroupHead.match(Unknown Source)
at java.util.regex.Pattern$Loop.match(Unknown Source)
at java.util.regex.Pattern$GroupTail.match(Unknown Source)
at java.util.regex.Pattern$BranchConn.match(Unknown Source)
at java.util.regex.Pattern$CharProperty.match(Unknown Source)
at java.util.regex.Pattern$Branch.match(Unknown Source)
at java.util.regex.Pattern$GroupHead.match(Unknown Source)
at java.util.regex.Pattern$Loop.match(Unknown Source)
at java.util.regex.Pattern$GroupTail.match(Unknown Source)
at java.util.regex.Pattern$BranchConn.match(Unknown Source)
at java.util.regex.Pattern$CharProperty.match(Unknown Source)
at java.util.regex.Pattern$Branch.match(Unknown Source)
at java.util.regex.Pattern$GroupHead.match(Unknown Source)
at java.util.regex.Pattern$Loop.match(Unknown Source)
at java.util.regex.Pattern$GroupTail.match(Unknown Source)
at java.util.regex.Pattern$BranchConn.match(Unknown Source)
at java.util.regex.Pattern$CharProperty.match(Unknown Source)
at java.util.regex.Pattern$Branch.match(Unknown Source)
at java.util.regex.Pattern$GroupHead.match(Unknown Source)
at java.util.regex.Pattern$Loop.match(Unknown Source)
at java.util.regex.Pattern$GroupTail.match(Unknown Source)
at java.util.regex.Pattern$BranchConn.match(Unknown Source)
at java.util.regex.Pattern$CharProperty.match(Unknown Source)
at java.util.regex.Pattern$Branch.match(Unknown Source)
at java.util.regex.Pattern$GroupHead.match(Unknown Source)
at java.util.regex.Pattern$Loop.match(Unknown Source)

显然它适用于某些输入而不是其他输入!或者是Java Regex引擎错误?

UPDATE3

这个正则表达式没有溢出和工作(java转义):“(,)(?=(?:[^ \”] | \“[^ \”] \“) $) “

1 个答案:

答案 0 :(得分:2)

正则表达式不适合跟踪某些内容是“内部”还是“外部”引号,括号,括号等;因此,执行此操作的最佳方法可能是按字符逐个字符串,并使用标记跟踪当前字符是否在一组引号内(此标志将启动为false并打开和关闭如遇到引号)。

但是,如果您确定要使用正则表达式执行此操作,我建议先使用引号(intermediate = line.split("\"");)拆分字符串,然后用逗号分隔中间列表中的每个元素,然后连接结果重新组合在一起。连接步骤有点棘手,因为您需要将每个数组的最后一个元素与下一个元素的第一个元素组合在一起,用引号将它们分开。

另一种可能性:首先用引号分割字符串,然后用奇数段中每个出现的逗号替换字符串中出现的某些字符序列(例如{{ 1}}),但留下偶数段(即那些代表引用段的段)。将段重新组合成单​​个字符串(当然,在每对段之间重新插入引号),然后按$split$的实例拆分字符串。