2016-06-19 46 views
1

我正在其中用戶輸入的一些數據,例如節目:劈裂字符串數組

222,「測試」,2 + 2

我不得不分割這個字符串用「」字符到一個數組,所以之前我就是用這個方法:

string[] parameters = userInput.Split (','); 

但是,現在它來到我的腦海如果用戶輸入的是這樣的:

345, 「測試,,,,,, ,,,,, ,,,,」,89

逗號只允許在我的項目中引號字符。

將該字符串拆分爲數組的最快方法是什麼?

編輯: 它不是解析CSV文件

編輯2:

預期返回{ 「345」, 「\」 測試,,,,,, ,,,,,, ,,, \ 「」, 「89」} - 此數組

+1

這聽起來有點像在C#解析CSV文件。有很多圖書館可以做得很好。 –

+1

使用'StringSplitOptions'作爲[Split function](https://msdn.microsoft.com/en-us/library/tabh47cf(v = vs.110).aspx)的第二個參數。 –

+1

[使用分隔符分隔,除非分隔符被轉義]可能的重複(http://stackoverflow.com/questions/4403194/split-using-delimiter-except-when-delimiter-is-escaped) – mariosangiorgio

回答

1

編輯2

假設要返回的參數恆定數目的在3個元素,則可能有興趣在Regex.Split function

var parameters = Regex.Split(userInput, @"^(?<first>\d+), (?<second>\D+), (?<third>\d+)$", 
            RegexOptions.ExplicitCapture) 
          .Where(a=>a!=string.Empty) 
          .ToList(); 

上面的代碼返回一個List<string>{345, "test ,,,,,, ,,,,, ,,,,", 89}

編輯3

如果你想返回一個數組,替換上面的代碼:

string[] parameters = Regex.Split(userInput, @"^(?<first>\d+), (?<second>\D+), (?<third>\d+)$", 
            RegexOptions.ExplicitCapture) 
          .Where(a=>a!=string.Empty) 
          .ToArray(); 

謝謝Lasee V. Karlsen的寶貴評論。

+1

實際上預計會返回一個3元素數組{「345」,「test ,,,,,, ,,,,, ,,,,」,「89」}。這完全是關於在引號中省略逗號。 – 107MP

+1

那麼....'.ToArray()'然後呢? –

+0

@ LasseV.Karlsen,這可能是一個選項;) –

0

我已經通過遍歷字符串來實現類似這樣的事情。你需要的是一個標誌,表明你是否在引用字符串內。

如果不在引用字符串內並遇到逗號,則會將當前位置的所有內容剪切到結果列表的新條目中。

當您在引用字符串之外遇到引號時,請設置該標誌。

設置標誌時,忽略所有逗號。當您遇到另一個報價時,請重新設置標誌。

這是粗略的算法。

也就是說,你可以看看Microsoft.VisualBasic.FileIo.TextFieldParser這個類,它可能已經做了你所需要的。別擔心,你可以在C#中使用它,也儘管命名空間

1

OP加EDIT2後,我張貼此
會離開,作爲和鍛鍊的OP

bool inQuote = false; 
bool inComma = true; 
List<string> words = new List<string>(); 
StringBuilder sb = new StringBuilder(); 
foreach (char c in input) 
{ 
    if(c == '"') 
    { 
     if(inQuote) 
     { 
     inComma = false; 
     if(!String.IsnullOrEmpty(sb.ToString()) 
     { 
      words.Add(sb.ToString().Trim; 
      sb.Clear(); 
     } 
     inQuote = !inQuote;    
     continue; 
     } 
    } 
    if (c == ',' && !inQuote) 
    { 
     if(inComma) 
     { 
     if(!String.IsnullOrEmpty(sb.ToString()) 
     { 
      words.Add(sb.ToString().Trim; 
      sb.Clear(); 
     } 
     inComma = !inComma; 
     continue; 
     } 
    } 
    sb.Add(c); 
} 
if(!String.IsnullOrEmpty(sb.ToString()) 
    words.Add(sb.ToString().Trim()); 
sb.Clear(); 
foreach (string s in words) 
{ 
    if(sb.Len > 0) 
     sb.Append(", "); 
    sb.Append(@"\"" + s + @"\""); // not sure if the is the correct syntax for " 
} 
Console.WriteLine(sb.ToString(); 

你需要處理與邊緣情況下,像

,SDLF 「aslkd」
,SDLF「aslkd,
什麼關於C也不是開放的?

當你考慮所有的可能性時,這對於Split或Regex來說太過分了。

+0

我真的不明白你想要做什麼。 – 107MP

+0

@ 107MP你是那個曾經的問題。你測試過了嗎? – Paparazzi

0

如果順序並不重要:

static void Main(string[] args) 
     { 
      string data = "345, \"test ,,,,,, ,,,,, ,,,,\", 89"; 

      string[] quoteValues = GetValueInQuote(data); 

      string[] result = data.Split(quoteValues, StringSplitOptions.RemoveEmptyEntries); 


      result = string.Join(string.Empty, result).Replace(" ", string.Empty).Split(new char[1]{','}, StringSplitOptions.RemoveEmptyEntries); 

      result = result.Concat(quoteValues).ToArray(); 

     } 

     static string[] GetValueInQuote(string data) 
     { 
      int quoteCount = data.Where(c => c == '\"').Count(); 



      if (quoteCount % 2 == 1) 
       throw new Exception("an odd number of quotes"); 


      string[] result = new string[quoteCount/2]; 



      for (int i = 0; i < result.Length; i++) 
      { 
       int first = data.IndexOf('\"'); 

       int second = data.IndexOf('\"', first + 1); 


       result[i] = data.Substring(first, second - first + 1); 
      } 

      return result; 

     }