2009-11-01 84 views
1

我有這個字符串:正則表達式,代替雙引號之間的所有逗號

1001,"Fitzsimmons, Des Marteau, Beale and Nunn",109,"George","COD","Standard",,109,8/14/1998 8:50:02 

我會用什麼正則表達式用管替換 "Fitzsimmons, Des Marteau, Beale and Nunn"逗號|所以它是:

"Fitzsimmons| Des Marteau| Beale and Nunn" 

應該澄清一點,我正在使用逗號分隔這個字符串,所以我想"Fitzsimmons, Des Marteau, Beale and Nunn"是一個字符串。我打算在分割後用逗號替換|

+1

這似乎是這將是WAY更快只是給自己寫一個小的狀態機循環,並用它做。 – 2009-11-01 22:15:11

+0

使用已經寫入的CSV解析器就會更快,就像鏈接到的一個jheddings一樣。 – 2009-11-01 22:25:43

+0

如果您要儘量使用正則表達式來進行替換,以便您可以使用常規拆分,那麼爲什麼不使用正則表達式來進行拆分呢?這樣你就不會不小心翻譯原始源代碼中的'|'(如果有的話) – SingleNegationElimination 2009-11-01 22:27:53

回答

4

我曾嘗試使用StringTokenizer,但它並不能很好的工作,所以在這裏,這似乎做你想要什麼代碼:

import java.util.*; 

public class JTest 
{ 
    public static void main(String[] args) 
    { 
    String str = "1001,\"Fitzsimmons, Des Marteau, Beale and Nunn\",109,\"George\",\"COD\",\"Standard\",,109,8/14/1998 8:50:02"; 
    String copy = new String(); 

    boolean inQuotes = false; 

    for(int i=0; i<str.length(); ++i) 
     { 
     if (str.charAt(i)=='"') 
      inQuotes = !inQuotes; 
     if (str.charAt(i)==',' && inQuotes) 
      copy += '|'; 
     else 
      copy += str.charAt(i); 
     } 

    System.out.println(str); 
    System.out.println(copy); 
    } 
} 
4

儘管可以使用正則表達式,但首先將行分割成字段然後再進行替換會更清晰。有一個很好的(免費的)用於解析稱爲opencsv的CSV文件的java庫。

1

我相信這對正則表達式來說會很困難。麻煩的是,正則表達式將不得不計算引號來確定它是否在兩個引號內。

實際上,.NET正則表達式引擎可以使用它的balanced matching功能。但我不認爲Java具有這種功能,我想不出沒有它的可靠方法。

您可能需要編寫一些過程代碼來完成此操作。

1

好了,這是一個CSV文件,所以我使用Ruby的內置CSV庫。然後,例如,您不必知道如何處理轉義的引號。

require 'csv' 
string =<<CSV 
1001,"Fitzsimmons, Des Marteau, Beale and Nunn",109,"George","COD","Standard",,109,8/14/1998 8:50:02 
CSV 
csv=CSV.parse string 
csv.each{|row| row.each {|cell| cell.gsub!(",","|") if cell.is_a?(String)}} 
outstring = "" 
CSV::Writer.generate(outstring){|out| csv.each {|row| out<<row}} 
+0

OP用Java標記了這個問題,所以我假設這是選擇的語言。 – jheddings 2009-11-01 22:30:31

+0

這不是一個紅寶石問題。 – SingleNegationElimination 2009-11-01 22:30:50

+0

所以也許在Java中嘗試http://sourceforge.net/projects/javacsv/。 – 2009-11-02 01:56:21

2

這裏有一點的Python,似乎這樣的伎倆:

>>> import re 
>>> p = re.compile('["][^"]*["]|[^,]*') 
>>> x = """1001,"Fitzsimmons, Des Marteau, Beale and Nunn",109,"George","COD","Standard",,109,8/14/1998 8:50:02""" 
>>> y = p.findall(x) 
>>> ','.join(z.replace(',','|') for z in y if z) 
'1001,"Fitzsimmons| Des Marteau| Beale and Nunn",109,"George","COD","Standard",109,8/14/1998 8:50:02' 

好像這個代碼轉成代碼高爾夫問題:-)

哎呀...錯過了Java標籤。

3

嘿布蘭登,你可以很容易地使用RE來做到這一點,通過使用後面和展望。見下文

String cvsString = "1001,\"Fitzsimmons, Des Marteau, Beale and Nunn\",109,\"George\",\"COD\",\"Standard\",,109,8/14/1998 8:50:02"; 
String rePattern = "(?<=\")([^\"]+?),([^\"]+?)(?=\")"; 
// first replace 
String oldString = cvsString; 
String resultString = cvsString.replaceAll(rePattern, "$1|$2"); 
// additional repalces until until no more changes 
while (!resultString.equalsIgnoreCase(oldString)){ 
    oldString = resultString; 
    resultString = resultString.replaceAll(rePattern, "$1|$2"); 
} 

結果字符串代碼會 1001,"Fitzsimmons| Des Marteau| Beale and Nunn",109,"George","COD","Standard",,109,8/14/1998 8:50:02

NingZhang.info

+0

這是一個有趣的方法。雖然我不明白你爲什麼需要向前看和向後看。這個正則表達式不會工作嗎? '(「[^」,] ++),([^「] ++」)' – 2009-11-02 13:46:55

+0

那麼前面/後面的查看是必需的,這樣任何令牌都可以包含逗號',',只要它是雙引號。否則,令牌不會被正確解析。 – Ning120 2010-02-04 01:31:39

相關問題