用于可选封闭的csv-string的Java正则表达式返回意外结果

时间:2016-09-24 06:56:21

标签: java regex

在Java中我有一个字符串(取自csv文件):

CSV_Worker

我的班级;会按给定的分隔符(public class CSV_Worker { Pattern pattern = null; int colCount = -1; public CSV_Worker (String delimiter, int colCount) { // (?<=^|;)(?:"([^;]*)"|([^;]*))(?=;|$) this.pattern = Pattern.compile("(?<=^|\\" + delimiter + ")(?:\"([^\\" + delimiter + "]*)\"|([^\\" + delimiter + "]*))(?=\\" + delimiter + "|$)"); this.colCount = colCount; } public String [] split (String line) { String [] result = new String[this.colCount]; Matcher m = pattern.matcher(line); int idx = 0; while (m.find()) { result[idx] = m.group(); idx++; } return result; } } )拆分它,并在必要时删除引号:

CSV_Worker.split(myString)

为什么40 "blue-collar" "married" ... 会返回

40
blue-collar
married
...

而不是

(?<=^|\|)"?((?<!")[^\|]*(?!")|(?<=")[^"]*(?="))"?(?=\||$)

修改

感谢@Fabian解决方案是另一个正则表达式:

<servlet>
        <servlet-name>projectHub</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/config/projectHub-servletConfig.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>projectHub</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>

enter image description here

Debuggex Demo

1 个答案:

答案 0 :(得分:2)

使用m.group(),您将获得整个匹配(即组0),而不仅仅是其中一个捕获组的内容。这包括非捕获组的引用。此外,对于有引号的情况和没有引号的情况,您使用不同的捕获组。因此,您需要使用Matcher,如下所示:

String g1 = m.group(1);
result[idx] = (g1 == null ? m.group(2) : g1);

您还可以使用lookarounds

仅使用一个捕获组
Pattern pattern = Pattern.compile("(?<=^|\\" + delimiter + ")\"?((?<!\")[^\\" + delimiter + "]*(?!\")|(?<=\")[^\"]*(?=\"))\"?(?=\\" + delimiter + "|$)");

允许您使用

result[idx] = m.group(1);
而是在分割方法中