2010-02-22 84 views
12

我问这个问题早些时候被关闭,因为它是一个重复的,这点我接受,实际上发现的问题Java: splitting a comma-separated string but ignoring commas in quotes的答案,所以拜谁发布它。拆分上逗号的字符串不包含双引号内与一捻

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

所以下面:

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

会为记号化:

  • 感谢,提前
  • 为(下称 “”, “帮助”)

我不知道是否有无论如何要修改当前的正则表达式我正在使用允许这一点,但任何指导将不胜感激。

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

期望的结果是什么? – DOK 2010-02-22 18:03:29

+12

你应该使用一个真正的CSV解析器来处理这个混乱。不**每个**解析问题最好用正则表达式处理。 – 2010-02-22 18:04:54

+1

@Joachim,你知道多少个CSV解析器能够以他想要的方式在引号内处理括号内的引号? – 2010-02-22 18:25:45

回答

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这样的标准格式来存储你的标记,这将会容易得多。

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为此,如果需要,我可以发布一些小技巧来从我发布的语法中获取解析器。

相关问题