java正则表达式拆分模式

时间:2012-07-10 08:20:12

标签: java

我想分割以下字符串:

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);
    }

    }             
}

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

2 个答案:

答案 0 :(得分: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));
        }
    }
}

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

答案 1 :(得分:0)

您的正则表达式会对[]执行一些奇怪的操作:使用这些内容并不像字符范围那样。出于这个原因,我没有打扰decypher并修复你的所有表达。

作为第二个注释,您应该确定正则表达式应该描述的内容:您希望它们与令牌之间的分隔符匹配,还是每个个别非分隔符令牌?使用split方法意味着前者,但我想对于您的应用程序,后者更容易实现。实际上在recent answer of mine中,我想出了一个匹配csv文件标记的正则表达式:

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

这将匹配

  • 不带引号的字符串,但不包括下一个逗号
  • qutoed字符串直至结束语,包括嵌入式逗号
  • 引用包含双引号的字符串

您可以使用此功能,为您的线路创建匹配器,使用find迭代所有匹配并使用group()提取令牌。如果您需要列的语义值,您可以使用该循环来删除引号并将双引号转换为单引号。

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