在逗号上拆分一个不带双引号的逗号的字符串

时间:2010-02-22 18:02:08

标签: java regex split

我之前提出过这个问题并且它已经关闭了,因为它是重复的,我接受并在Java: splitting a comma-separated string but ignoring commas in quotes问题中找到答案,所以感谢发布它的人。

但我已经遇到了另一个问题。显然我需要做的是当有零或偶数个双引号时使用“,”作为我的分隔符,但也忽略括号中包含的任何“,”。

以下内容:

"Thanks,", "in advance,", "for("the", "help")"

将标记为:

  • 谢谢,
  • 提前,
  • for(“the”,“help”)

我不确定是否还有修改我正在使用的当前正则表达式,但是任何指导都将不胜感激。

line.split(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)");

2 个答案:

答案 0 :(得分:5)

有时候更容易匹配你想要的东西而不是你想要的东西:

String s = "\"Thanks,\", \"in advance,\", \"for(\"the\", \"help\")\"";
String regex = "\"(\\([^)]*\\)|[^\"])*\"";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(s);
while(m.find()) {
    System.out.println(s.substring(m.start(),m.end()));
}

输出:

"Thanks,"
"in advance,"
"for("the", "help")"

如果你还需要忽略括号内引号部分内的右括号,那么你需要这个:

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

需要第二个更复杂版本的字符串示例是:

 "foo","bar","baz(":-)",":-o")"

输出:

"foo"
"bar"
"baz(":-)",":-o")"

但是,如果可能,我建议您更改数据格式。如果您使用像XML这样的标准格式来存储令牌,这将会容易得多。

答案 1 :(得分:3)

自行开发的解析器很容易编写。

例如,这个ANTLR语法可以毫不费力地处理你的示例输入:

parse
  :  line*
  ;

line
  :  Quoted ( ',' Quoted )* ( '\r'? '\n' | EOF )
  ;

Quoted
  :  '"' ( Atom )* '"'
  ;

fragment
Atom
  :  Parentheses
  |  ~( '"' | '\r' | '\n' | '(' | ')' )
  ;

fragment
Parentheses
  :  '(' ~( '(' | ')' | '\r' | '\n' )* ')'
  ;

Space
  :  ( ' ' | '\t' ) {skip();}
  ;

并且可以很容易地将其扩展为考虑转义引号或括号。

在将由该语法生成​​的解析器提供给以下两行输入时:

"Thanks,", "in advance,", "for("the", "help")"
"and(,some,more)","data , here"

它被解析如下:

alt text http://i47.tinypic.com/258otvs.png

如果您考虑使用ANTLR,我可以发布一些HOW-TO来从我发布的语法中获取解析器,如果您愿意的话。