Java 使用逗号拆分不包含在双引号中的字符串

Java 使用逗号拆分不包含在双引号中的字符串,java,regex,split,Java,Regex,Split,我早些时候问过这个问题,它被关闭了,因为它是一个副本,我接受了,并在问题中找到了答案,所以感谢发布它的人 但后来我遇到了另一个问题。显然,当双引号为零或偶数时,我需要使用“,”作为分隔符,但也要忽略括号中包含的任何“,” 因此,以下是: "Thanks,", "in advance,", "for("the", "help")" 将标记为: 谢谢 事先 为了(“帮助”) 我不确定是否有任何方法可以修改我正在使用的当前正则表达式,以实现这一点,但任何指导都将不胜感激 line.split("

我早些时候问过这个问题,它被关闭了,因为它是一个副本,我接受了,并在问题中找到了答案,所以感谢发布它的人

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

因此,以下是:

"Thanks,", "in advance,", "for("the", "help")"
将标记为:

  • 谢谢
  • 事先
  • 为了(“帮助”)
我不确定是否有任何方法可以修改我正在使用的当前正则表达式,以实现这一点,但任何指导都将不胜感激

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

有时,更容易匹配您想要的而不是您不想要的:

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")"
"foo"
"bar"
"baz(":-)",":-o")"
如果还需要它忽略括号内引号部分中的结束括号,则需要:

 String regex = "\"(\\((\"[^\"]*\"|[^)])*\\)|[^\"])*\"";
需要第二个更复杂版本的字符串示例如下:

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

"Thanks,"
"in advance,"
"for("the", "help")"
"foo"
"bar"
"baz(":-)",":-o")"
但是,如果可能的话,我建议您更改数据格式。如果您使用标准格式(如XML)来存储令牌,这将容易得多。

自制的解析器很容易编写

例如,此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"
它的解析方式如下:


如果你考虑使用ANTLR,如果你愿意,我可以用一点方法从我所发布的语法中得到解析器。

你应该使用一个真正的CSV解析器来处理这个混乱。并不是所有的解析问题都能用正则表达式来解决。@Joachim,你知道有多少CSV解析器可以按他想要的方式处理引号、括号内的引号和引号?没有,因为它是无效的CSV格式。它不是CSV。它是函数调用的参数列表。我也意识到我最初的输入是不正确的。不应在(“the”、“help”)周围加上双引号。