2016-04-14 202 views
0

基本上我正在處理CSV文件並在C#中逐行讀取它。我有一個字符串輸入(一行),並試圖找到一個正則表達式模式,並使用另一個正則表達式模式替換它,但結果不是我所期望的。使用正則表達式替換模式替換字符串

var input = "\"efgh ,ijkl123,\",abcd , \"efgh ,ijkl123,\",mnop456 \"efgh ,ijkl123,\""; 

在輸出我需要用分號其中那些雙引號是逗號彼此之間更換雙引號之間的內部逗號。

雙引號和外部逗號(雙引號外的逗號之間)它可以只有空格。

因此,我希望輸出爲:"efgh ;ijkl123,",abcd , "efgh ;ijkl123,",mnop456 "efgh ,ijkl123,"

我的代碼:

var pattern = @".*,\s*""(.*,+.*)+""\s*,.*"; 
var replacePattern = @".*,\s*""(.*;+.*)+""\s*,.*"; 
if (Regex.IsMatch(input, pattern)) 
{ 
    var output = Regex.Replace(input, pattern, replacePattern); 
} 

但在運行我的代碼,輸出爲:。 ,\ s「(。; +。)+」\ s *,。*這是replacePattern。

EDIT更多輸入採樣,並輸出作爲預期:

  1. 輸入abcd , "efgh ,ijkl123,",mnop456

    輸出abcd , "efgh ;ijkl123;",mnop456

  2. 輸入"efgh ,ijkl123,",abcd , "efgh ,ijkl123,",mnop456 "efgh ,ijkl123,"

    輸出"efgh ;ijkl123;",abcd , "efgh ;ijkl123;",mnop456 "efgh ,ijkl123,"

  3. 輸入,"efgh ,ijkl123,",abcd" , "efgh ijkl123,",mnop456 "efgh ,ijkl123,","efgh ,ijkl123,"mnop456

    輸出,"efgh ;ijkl123;",abcd" , "efgh ijkl123;",mnop456 "efgh ,ijkl123,","efgh ,ijkl123,"mnop456

  4. 輸入,"efgh" ,ijkl123,",abcd" , "efgh ijkl123,",mnop456 "efgh ,ijkl123,","efgh ,ijkl123,"mnop456

    輸出,"efgh" ,ijkl123,";abcd" , "efgh ijkl123;",mnop456 "efgh ,ijkl123,","efgh ,ijkl123,"mnop456

  5. 輸入efgh ,ijkl123,",abcd , "efgh ,ijkl123,",mnop456 "efgh ,ijkl123,"

    輸出efgh ,ijkl123,",abcd , "efgh ;ijkl123;",mnop456 "efgh ,ijkl123,"

+0

什麼,我從你的陳述讀書是要替換','和'昏迷;'分號,如果它是間雙引號? – Saleem

+0

如果字符串超過2個雙引號,期望的行爲是什麼? – Zee

+0

是的,那雙雙引號也是逗號之間的。如果我想簡化,它會是這樣的: ,「,」,=>,「;」, –

回答

1

好吧,這有點棘手,我敢肯定有人會建議比我更好的正則表達式。假設你輸入的文字是:

"efgh ,ijkl123,",abcd , "efgh ,ijkl123,",mnop456 "efgh ,ijkl123," 

你可以試試:

var data = "\"efgh ,ijkl123,\",abcd , \"efgh ,ijkl123,\",mnop456 \"efgh ,ijkl123,\""; 

var rx = @"(?<=(^|,[ \t]*))\""[^\""\n]+\""(?=[ \t]*(,|$))"; 

var matches = Regex.Matches (data, rx); 

foreach (Match match in matches) { 
    data = new Regex (match.Value). 
     Replace(data, match.Value.Replace (',', ';'), 1); 
} 

Console.WriteLine (data); 

它會發出:

"efgh ;ijkl123;",abcd , "efgh ;ijkl123;",mnop456, "efgh ,ijkl123," 

以上代碼基本上與;半結腸代替雙引號之間的所有,昏迷。

+0

不錯的一個!但在你的例子中它應該是2個匹配而不是3個,最後一個不匹配,因爲我想要的是外部逗號(雙引號外的逗號)和雙引號之間的空格。 –

+0

嗯,在這種情況下,我的示例輸入是不正確的。這不是有效的CSV文件。你能用有效的字符串嘗試一下,看看它是如何發生的。你可以試試regex101(鏈接貼在上面)。無論如何,我已經更新了我的示例輸入和預期的輸出字符串。 – Saleem

+0

沒有您的示例輸入很好,它是一個標準的CSV格式。我將採用它作爲我的輸入。 –

0

不知道它是非常有效的,但工程。歡迎提出進一步改進建議。

string input = "\"efgh ,ijkl123,\",abcd , \"efgh ,ijkl123,\",mnop456 \"efgh ,ijkl123,\"";; 

Regex.Matches(input, "\"([^\"]*)\"(,)") // Extract string between quotes followed by ','. 
.Cast<Match>() 
    .ToList() 
    .ForEach(m=> input = input.Replace(m.Value, m.Value.Replace(",",";")) // for each match replace with ';' inserted match. 
           .Replace(";\";",",\",")); // a hack, should have done it better 

輸出繼電器:

"efgh ;ijkl123,",abcd , "efgh ;ijkl123,",mnop456 "efgh ,ijkl123," 

工作Demo

+0

謝謝!我剛剛編輯了我的帖子。在雙引號和外部逗號之間(雙引號之外的逗號)它只能是空格。所以如果我在你的代碼中使用這個輸入,我希望2替換爲3: var input =「\」efgh,ijkl123,\「,abcd,\」efgh,ijkl123,\「,mnop456 \」efgh,ijkl123, \ 「」; –

+0

@AmirChatrbahr現在更新,請檢查。 –

+0

它沒有爲此工作:「\」efgh,ijkl123,\「,abcd,\」efgh,ijkl123,\「,mnop456 \」efgh,ijkl123,\「」我得到了「\」efgh; ijkl123 \ 「,abcd,\」efgh; ijkl123,\「,mnop456 \」efgh,ijkl123,\「」 –