-4

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

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 提出正确的问题,Google 的第一个结果应该是您最可能寻找的结果;)。

第一个结果,正则表达式在引号之外选择逗号

正则表达式是这样的:(,)(?=(?:[^"']|["|'][^"'] ") $)。

测试和工作..

最后,我假设编程技能和理解技能之间存在差异,它们肯定不是许多程序员都具备的。我在几个地方问过,大多数人说这是不可能的……显然是的。

感谢您的时间,抱歉,也许急于寻求帮助。

这个网站很棒!:)

更新2

这个正则表达式 (,)(?=(?:[^"']|["|'][^"'] ") $)。给我 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 正则表达式引擎有问题?

更新3

此正则表达式不会溢出并且有效(java 转义): "(,)(?=(?:[^\"]|\"[^\"] \") $)"

4

1 回答 1

2

正则表达式不利于跟踪某事物是“内部”还是“外部”引号、方括号、圆括号等;因此,最好的方法可能是逐个字符地遍历字符串,并使用一个标志来跟踪当前字符是否在一组引号内(这个标志将开始为假并打开和关闭因为遇到引号)。

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

另一种可能性:首先用引号将字符串分割,然后将奇数段中出现的每个逗号替换为字符串中其他任何地方都没有出现的字符序列(例如$split$),但保留偶数段(即,那些代表引用的部分)单独。将这些段重新组合成一个字符串(当然,在每对段之间重新插入引号),然后按$split$.

于 2012-12-07T03:52:15.027 回答