我早些时候问过这个问题,它被关闭了,因为它是重复的,我接受了它,并在Java问题中找到了答案:拆分逗号分隔的字符串,但忽略引号中的逗号,因此感谢发布者。
但是从那以后,我遇到了另一个问题。 显然,当双引号为零或偶数时,我需要使用","作为分隔符,但也忽略括号中包含的任何","。
因此,以下内容:
"Thanks,","in advance,","for("the","help")"
将标记为:
谢谢,
提前,
for(" the"," help")
我不确定是否有必要修改我正在使用的当前正则表达式以允许这样做,但是任何指导都将不胜感激。
line.split(",(?=([^"]*"[^"]*")*[^"]*$)");
预期的结果是什么?
您应该使用真正的CSV解析器来处理该混乱情况。 并非每个解析问题都可以使用正则表达式来最好地解决。
@Joachim,您知道有多少个CSV解析器可以按他想要的方式处理引号,方括号,内引号?
无,因为其无效的CSV格式。
它不是CSV。 它是函数调用的参数列表。 我还意识到我的原始输入不正确。 for(" the"," help")周围不应包含双引号。
有时,匹配您想要的东西比不想要的东西更容易:
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之类的标准格式来存储令牌,这会容易得多。
自行编写的解析器很容易编写。
例如,此ANTLR语法可以轻松处理示例输入:
parse
: line*
;
line
: Quoted ( ',' Quoted )* ( '
'? '
' | EOF )
;
Quoted
: '"' ( Atom )* '"'
;
fragment
Atom
: Parentheses
| ~( '"' | '
' | '
' | '(' | ')' )
;
fragment
Parentheses
: '(' ~( '(' | ')' | '
' | '
' )* ')'
;
Space
: ( ' ' | '\t' ) {skip();}
;
并且很容易扩展此范围以考虑转义的引号或括号。
将由该语法生成??的解析器输入以下两行输入时:
"Thanks,","in advance,","for("the","help")"
"and(,some,more)","data , here"
它像这样被解析:
如果您考虑为此使用ANTLR,我可以发布一些HOW-TO来从我发布的语法中获取解析器(如果需要)。