0

我想拆分以下字符串:

String line ="DOB,1234567890,11,07/05/12,\"first,last\",100,\"is,a,good,boy\"";

分为以下标记:

DOB
1234567890
11
07/05/12
first,last
100
is,a,good,boy

我尝试使用以下正则表达式:

import java.util.*;
import java.lang.*;
import java.util.regex.*;
import org.apache.commons.lang.StringUtils;

class SplitString{

    public static final String quotes = "\".[[((a-z)|(A-Z))]+( ((a-z)|(A-Z)).,)*.((a-z)|(A-Z))].\"" ;
    public static final String ISSUE_UPLOAD_FILE_PATTERN = "((a-z)|(A-Z))+ [(((a-z)|(A-Z)).,)* + ("+quotes+".,) ].((a-z)|(A-Z)) + ("+quotes+")";

    public static void main(String[] args){

        String line ="DOB,1234567890,11,07/05/12,\"first,last\",100,\"is,a,good,boy\"";
        String delimiter = ",";

    Pattern p = Pattern.compile(ISSUE_UPLOAD_FILE_PATTERN);

    Pattern pattern = Pattern.compile(ISSUE_UPLOAD_FILE_PATTERN);
    String[] output = pattern.split(line);

    System.out.println(" pattern: "+pattern);

    for(String a:output){
        System.out.println(" output: "+a);
    }

    }             
}

我在正则表达式中遗漏了什么吗?

4

2 回答 2

1

这是您的代码的更新版本,可为您提供预期的输出:

public static final String ISSUE_UPLOAD_FILE_PATTERN = "(?<=(^|,))(([^\",]+)|\"([^\"]*)\")(?=($|,))";
public static void main(String[] args) {
    String line = "DOB,1234567890,11,07/05/12,\"first,last\",100,\"is,a,good,boy\"";
    Matcher matcher = Pattern.compile(ISSUE_UPLOAD_FILE_PATTERN).matcher(line);
    while (matcher.find()) {
        if (matcher.group(3) != null) {
            System.out.println(matcher.group(3));
        } else {
            System.out.println(matcher.group(4));
        }
    }
}

正则表达式的工作方式如下 (?<=(^|,))::检查匹配前的字符是字符串的开头还是 a ,
(([^\",]+)|\"([^\"]*)\"):匹配"<any number of (not")>"或者any number of (not" or ,)
(?=($|,)):检查匹配后的字符是字符串的结尾还是 a,
结果将是 i 组 3 或 4,具体取决于哪个部分匹配。

于 2012-07-10T08:45:49.167 回答
0

你的正则表达式用[and做了一些奇怪的事情]:这些的使用看起来不像字符范围。出于这个原因,我没有费心去破译和修复你所有的表情。

作为第二个注意事项,您应该确保您的正则表达式应该描述什么:您希望它们匹配标记之间的分隔符,还是每个单独的非分隔符标记?使用 split 方法意味着前者,但我猜对于您的应用程序,后者更容易实现。事实上,在我最近的回答中,我想出了一个匹配 csv 文件标记的正则表达式:

String tokenPattern = "\"[^\"]*(\"\"[^\"]*)*\"|[^,]*";

这将匹配

  • 不加引号的字符串,直到但不包括下一个逗号
  • qutoed 字符串直到结束引号,包括嵌入的逗号
  • 带引号的字符串,包括双引号

您可以使用它,为您的行创建一个匹配器,使用 遍历所有匹配项find并使用group(). 如果您需要列的语义值,您也可以使用该循环去除引号并将双引号转换为单引号。

作为替代方案,您当然也可以按照问题评论中的建议使用 CSV 阅读器。

于 2012-07-10T08:42:52.433 回答