2010-03-27 54 views
1

我需要解析其中列由列分隔的字符串輸入和包含在數據中的逗號的任何字段被包裝在引號(逗號分隔,引用的文字標識)。對於這個項目,我需要刪除引號和引號對之間發生的任何逗號。基本上,我需要刪除包含在字段中的逗號和引號,同時保留用於分隔字段的逗號。這裏有一個小的代碼,我放在一起處理簡單的場景:解析逗號和quotemarks在退化CSV文件中使用正則表達式

// Sample input 1: This works and covers 99% of the records that I need to parse. 
string str1 = "[email protected],2010/03/27 12:2:02,,some_first_name,some_last_name,,\"This Address Works, Suite 200\",Some City,TN,09876-5432,9795551212x123,XYZ"; 
str1 = Regex.Replace(str1, "\"([^\"^,]*),([^\"^,]*)\"", "$1$2"); 
Console.WriteLine(str1); 
// Outputs: [email protected],2010/03/27 12:2:02,,some_first_name,some_last_name,,This Address Works Suite 200,Some City,TN,09876-5432,9795551212x123,XYZ 

儘管此代碼適用於大多數的我的記錄,當一個字段包含不止一個逗號這是行不通的。我想要做的是修改代碼,以便刪除列中包含的逗號的每個實例,而不管該字段中有多少個逗號。我不想硬編碼只處理2個逗號,3個逗號或25個逗號。該代碼應該刪除該字段中的所有逗號。以下是我的代碼無法正確處理的示例。

// Sample input 2: This doesn't work since there is more than 1 comma between the quotes. 
string str2 = "[email protected],2010/03/27 12:2:02,,some_first_name,some_last_name,,\"i,l,k,e, c,o,m,m,a,s, i,n ,m,y, f,i,e,l,d\",Some City,TN,09876-5432,9795551212x123,XYZ"; 
str2 = Regex.Replace(str2, "\"([^\"^,]*),([^\"^,]*)\"", "$1$2"); 
Console.WriteLine(str2); 
// Desired output: [email protected],2010/03/27 12:2:02,,some_first_name,some_last_name,,i like commas in my field,Some City,TN,09876-5432,9795551212x123,XYZ 

我該如何用正則表達式來實現?

+3

格式你所描述的匹配準確CSV。爲什麼不使用現有的CSV解析器? – 2010-03-27 20:20:19

+0

我正在使用SSIS導入幾千個傳統日誌文件。但是,這些文件存在數據質量問題。有些文件有13列,有些列有14列,有些引用包含逗號的文本字段,有些不使用引號併產生「額外」列等等。我描述的更多問題,但是我已經能夠在我的數據流中通過腳本轉換來處理它們 - 除了帖子中描述的問題之外。 – 2010-03-29 06:19:54

回答

3

匹配的報價和正則表達式不齊頭並進,你可能會更好使用CSV解析器,邁克爾·馬德森建議的。
但是,如果你知道你所期望的行情纔會出現,你可以這樣做以下:

str2 = Regex.Replace(str2, "\"[^\"]*\"", 
        match => match.Value.Trim('\"').Replace(",", "")); 
+0

不應該是最後一位是'.Replace( 「」, 「」)'? – 2010-03-27 22:18:28

+0

@Alan Moore - 當然。謝謝。 – Kobi 2010-03-28 08:42:44

+0

@註冊用戶 - 謝謝!順便說一下,這是一個lambda表達式 - 一個匿名函數,就像從之前版本的C#中的'委託'一樣。在某種程度上它看起來比賽,但以一種微妙的方式。 – Kobi 2010-03-29 08:30:22

2

這裏是一個純粹的正則表達式版本:

str2 = Regex.Replace(str0, 
      @"""|,(?=(?>[^""]*""[^""]*(?:""[^""]*""[^""]*)*)$)", 
      String.Empty); 

它匹配任何引號,或如果後面跟着一個奇數的引號,就用一個逗號代替,然後用空格代替。

我只會走這條路,如果我絕對必須,例如,如果我用一個框架,才讓我指定的正則表達式和替換字符串工作。否則,我會選擇@ Kobi的方法(因爲它的可讀性更強)或者使用專用的CSV處理器。他們不難找到。

+0

我用了Kobi的辦法去,因爲它不必只限於正則表達式。我只是假設必須有一種方法來使用正則表達式,因爲它似乎是解決這個問題的合適工具。不過,我肯定會檢查你的代碼,看看我能否理解它並從中學習一些有用的東西。 – 2010-03-29 06:28:45