2012-11-06 145 views
3

可能重複:
Parsing CSV input with a RegEx in java正則表達式在Java讀取CSV

我在每一行具有以下形式的字符串的輸入值的輸入文件:

" ab cd " , " efgh,ijk.", 4,"lmno" 

即,

  1. 單詞要麼在引號中,要麼沒有引號。
  2. 不允許分別在開始和結束詞之前和之後的空格。

編輯:3.它可以具有輸入只由逗號分隔的(abc,"Hi Mary,Joe",5

使用.Split()在Java中,我需要一個正則表達式以將其輸出:

ab cd 
efgh,ijk. 
4 
lmno 

我嘗試這樣做:

[^",]*[\",] 

但這並不對"efgh,ijk."

工作

這裏是一個正則表達式測試的鏈接:http://regexpal.com/ 我需要一些幫助。請幫忙。 謝謝

+4

這就是[CSV格式](http://tools.ietf.org/html/rfc4180)。這種格式的[大量](https://www.google.com/search?q=java+csv+parser)解析器。你甚至可以自己輕鬆[寫一個](http://stackoverflow.com/a/2241950)。不要試圖將正則表達式用於非規則模式,它只會傷害你。 – BalusC

+0

'5,ebo'eu ooeu「euoe,oeuou'應該如何處理? – durron597

+0

@ durron597 - 這違反了OP的輸入條件。值應該沒有引號或用引號括起來。 –

回答

2

DEMO

正則表達式:(?:\s*(?:\"([^\"]*)\"|([^,]+))\s*,?)+?

更新爲空值:(?:\s*(?:\"([^\"]*)\"|([^,]+))\s*,?|(?<=,)(),?)+?DEMO

它的工作的一個例子,我知道這是有點CSV格式,但只要你不寫真的很奇怪的事情,它會匹配所有的人。

Matcher ma = Pattern.compile("(?:\\s*(?:\\\"([^\\\"]*)\\\"|([^,]+))\\s*,?)+?").matcher(" \" ab cd \" , \" efgh,ijk.\", 4,\"lmno\""); 
while (ma.find()) { 
    if (ma.group(1) == null) { 
     System.out.println(ma.group(2)); 
    } else { 
     System.out.println(ma.group(1)); 
    } 
} 

編輯,順便說一句,如果你希望我們給你的代碼,並沒有告訴我們關於一個正則表達式在線測試儀,如果你這樣做,那是因爲你知道如何處理正則表達式,如果你不知道如何做到這一點,也可以問問。

+0

這需要引號以及後面的逗號。 – Crocode

+0

但是,當我執行程序時只打印空格和逗號 – Crocode

+0

因爲你用null或\ n替換它,所以我給了你一個反向引用,你只需要循環它並得到它們。 –

1

嘗試撥打split()(?:^\s*"\s*|\s*"\s*$|\s*"?\s*,\s*"?\s*)demo)。

這將匹配包含在一個字符串中的逗號,這在您的情況中是錯誤的。但是如果你打算使用split()這是唯一的方法。你可以引入一些方法來轉義包含逗號(如\,),這可以很容易地添加到正則表達式中。

否則你將不得不使用一些其他的方式來解除字符串,並且split()不會幫助你。

0

如果你不想使用正則表達式,正則表達式意味着它是一個'regular' expression。 「我認爲這裏有一種模式」並不是正則表達式。它們很好,速度很快,我只在完全控制輸入到正則表達式中的輸入時才使用它們。

//no development environment up, there may be compilation errors. 
private static String[] csv(final String input){ 
    String[] inputArray = input.split(","); 
    for(int i =0;i < inputArray.length;i++){ 
//org.apache.commons.lang.StringUtils 
    String value = StringUtils.removeEnd(inputArray[i],"\""); 
    value = StringUtils.removeStart(value,"\""); 
    value = StringUtils.trim(value); 

    inputArray[i] = value; 
    } 
    return inputArray; 
} 
+0

您應該修整字符串兩次:在字符串結尾和字符串開頭刪除*「*之前和之後 –

+0

如果字符串是」a,b,c「,」def「則會拆分爲abc def。它是a,b,c和def – Crocode

2

我建議找到匹配,然後修剪它們以獲得最終結果。

Matcher m = Pattern.compile("\\s*(?:\"[^\"]*\"|(?:^|(?<=,))[^,]*)").matcher(s); 
while (m.find()) { 
    System.out.println(m.group().replaceAll("^\\s*\"?\\s*(.*?)\\s*\"?\\s*$", "$1")); 
} 

請參閱this demo