2017-05-31 59 views
-2

我需要拆分逗號分隔的字符串,哪些內容有時在引號之間。一個例子可以是:拆分分隔字符串並刪除轉義序列

1, 「TEST」,22345 「18,95」,AB「CDE

這裏的第一個問題是分裂,只有當逗號不包圍字符串我用一個簡單的正則表達式做了這個,接下來的問題是剪掉引號,它們圍繞着內容,對於「測試」和「18,95」,引號應該被刪除Ab「cde中的引用應該保持不變。這是我到目前爲止的代碼:

List<string> results = Regex.Matches(this.Content, @"[\""](.+?)[\""]|[^,]+") 
          .Cast<Match>() 
          .Select(m => m.Value) 
          .Select(s => s.StartsWith("\"") && s.EndsWith("\"") ? s.Remove(1,1).Remove(s.Length-1,1) : s) 
          .ToList(); 

對於第二Select我得到一個ArgumentOutOfRangeException因爲第二Removes工作了。我認爲它應該工作,但不知何故。

如果有更好的方法來做到這一點,我會很樂意瞭解它。

+0

你嘗試一個CSV解析器? –

+0

提示:字符串是不可變的。 – Karolis

+0

@WiktorStribiżew我試圖執行一個 –

回答

2

您可以用相同的名字捕捉引號和引號值之間的值命名捕捉組和檢索Match.Groups["group_name"]匹配的捕獲:

List<string> results = Regex.Matches(this.Content, @"[\""](?<value>.+?)[\""]|(?<value>[^,]+)") 
    .Cast<Match>() 
    .Select(m => m.Groups["value"].Value) 
    .ToList(); 

演示:https://dotnetfiddle.net/M8lJDR

考慮到帳戶潛在空值更改爲+*並用(?<=^|,)(?=,|$)圍繞正則表達式:

List<string> results = Regex.Matches(input, 
     @"(?<=^|,)(?:""(?<value>.*?)""|(?<value>[^,]*))(?=,|$)") 
    .Cast<Match>() 
    .Select(m => m.Groups["value"].Value) 
    .ToList(); 

演示:https://dotnetfiddle.net/WqRD20

+0

哇的答案。這是一個很好的!完善。你也許還有一個想法,我如何調整正則表達式來捕獲空值。就像在1,2,4中那樣,會有一個空的第三位,這應該導致一個空字符串 –

+0

只需將量詞從'+'換成'*'即可。看到更新的演示 –

+0

我也想到了這一點,但不幸的是,在我需要清理每個'正常'結果後,它會增加一個空結果 –

0

調用s.Remove(1,1)之後,結果字符串將短於s(保持不變)!使用替代

s.Remove(1,1).Remove(s.Length-2,1) 

s.Remove(s.Length-1,1).Remove(1,1) 

s.Remove(1,1).Remove(s.Length-1,1) 

釷當s="\""仍然會失敗。爲了彌補這一點,你必須更新的條件:

s.StartsWith("\"") && s.EndsWith("\"") && s.Length > 1 ? s.Remove(s.Length-1,1).Remove(1,1) : s 
+0

我已經嘗試過。也不起作用 –

0

如何使用.Substring()

List<string> results = Regex.Matches(content, @"[\""](.+?)[\""]|[^,]+") 
         .Cast<Match>() 
         .Select(m => m.Value) 
         .Select(s => s.StartsWith("\"") && s.EndsWith("\"") 
          ? s.Substring(1, s.Length - 2) : s) 
         .ToList(); 

輸出:

1 
TEST 
22345 
18,95 
Ab"cde 

注:不正常的部分工作其中包含2個以上的引號。Ë""test""work"",1

+0

但是,這正是我不想要的,因爲報價仍然在結果 –

+0

@RomanoZumbé猜我錯過了。更新了使用'.Substring()'而不是 – degant

0

也許你可以通過每個results和循環:

for (int i=0; i < results.Count; i++) 
{ 
    if (results[i].StartsWith("\"")) 
     results[i] = results[i].Remove(0, 1); 

    if (results[i].EndsWith("\"")) 
     results[i] = results[i].Remove(results[i].Length - 1, 1); 
}