2010-02-22 146 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爲此,如果需要,我可以發佈一些小技巧來從我發佈的語法中獲取解析器。

相關問題