2013-12-20 138 views
2

如何使用带逗号的逗号分隔逗号分隔的字符串?C#拆分逗号分隔值

示例输入

John, Doe, "Sid, Nency", Smith 

预期输出

  • 约翰
  • Doe的
  • 西特,Nency
  • 史密斯

以逗号分割是可以的,但我要求允许字符串“Sid,Nency”。我试图用正则表达式来分割这些值。正则表达式",(?=([^\"]*\"[^\"]*\")*[^\"]*$)"来自Java的问题,它不适合我的.NET代码。它加倍了一些字符串,发现额外的结果等。

那么什么是拆分这种字符串的最佳方式?

+0

它看起来像你处理CSV输入?如果是这样,*请*使用CSV库 - 有很多好的,它会为您节省很多的痛苦!如果您不是,请澄清您的问题,以解释为什么CSV库不适合... –

+0

不,它不是一个CSV文档。这只是一个字符串 – Andrei

+0

RB,如果你给我看,我会很高兴,我怎么能用Csv Lib来处理这个问题 – Andrei

回答

4

这是因为捕获组。只要把它变成一个非捕获组:

",(?=(?:[^""]*""[^""]*"")*[^""]*$)" 
     ^^ 

捕获组包括捕获的部分在你的结果。

ideone demo

var regexObj = new Regex(@",(?=(?:[^""]*""[^""]*"")*[^""]*$)"); 
regexObj.Split(input).Select(s => s.Trim('\"', ' ')).ForEach(Console.WriteLine); 

而刚刚修剪的结果。

+0

谢谢!这只是作品! – Andrei

1

只要通过你的字符串。如果您处于“阻止”状态,则在您穿过字符串时请保持轨迹
。如果你是 - 不要将逗号作为
逗号(作为分隔符)。否则,请像这样对待它。这是一个简单的
算法,我会自己写。当你遇到第一个“你输入
一个块。当你遇到下一个”,你结束了你的那个块,等等。
所以你可以通过你的字符串一次。

import java.util.ArrayList; 


public class Test003 { 

    public static void main(String[] args) { 
     String s = " John, , , , \" Barry, John \" , , , , , Doe, \"Sid , Nency\", Smith "; 

     StringBuilder term = new StringBuilder(); 
     boolean inQuote = false; 
     boolean inTerm = false; 
     ArrayList<String> terms = new ArrayList<String>(); 
     for (int i=0; i<s.length(); i++){ 
      char ch = s.charAt(i); 
      if (ch == ' '){ 
       if (inQuote){ 
        if (!inTerm) { 
         inTerm = true; 
        } 
        term.append(ch); 
       } 
       else { 
        if (inTerm){ 
         terms.add(term.toString()); 
         term.setLength(0); 
         inTerm = false; 
        } 
       } 
      }else if (ch== '"'){ 
       term.append(ch); // comment this out if you don't need it 
       if (!inTerm){ 
        inTerm = true; 
       } 
       inQuote = !inQuote; 
      }else if (ch == ','){ 
       if (inQuote){ 
        if (!inTerm){ 
         inTerm = true; 
        } 
        term.append(ch); 
       }else{ 
        if (inTerm){ 
         terms.add(term.toString()); 
         term.setLength(0); 
         inTerm = false; 
        } 
       } 
      }else{ 
       if (!inTerm){ 
        inTerm = true; 
       } 
       term.append(ch); 
      } 
     } 

     if (inTerm){ 
      terms.add(term.toString()); 
     } 

     for (String t : terms){ 
      System.out.println("|" + t + "|"); 
     } 

    } 



} 
+0

以及这是一个想法 – Andrei

+0

@AndreiMikhalevich好的,我只是举例说明了一些代码。 –

0

我用下面的代码我的CSV分析器类中实现这一点:

private string[] ParseLine(string line) 
    { 
     List<string> results = new List<string>(); 
     bool inQuotes = false; 
     int index = 0; 
     StringBuilder currentValue = new StringBuilder(line.Length); 
     while (index < line.Length) 
     { 
      char c = line[index]; 
      switch (c) 
      { 
       case '\"': 
        { 
         inQuotes = !inQuotes; 
         break; 
        } 

       default: 
        { 
         if (c == ',' && !inQuotes) 
         { 
          results.Add(currentValue.ToString()); 
          currentValue.Clear(); 
         } 
         else 
          currentValue.Append(c); 
         break; 
        } 
      } 
      ++index; 
     } 

     results.Add(currentValue.ToString()); 
     return results.ToArray(); 
    } // eo ParseLine 
0

如果你发现正则表达式太复杂,你可以做这样的:

string initialString = "John, Doe, \"Sid, Nency\", Smith"; 

IEnumerable<string> splitted = initialString.Split('"'); 
splitted = splitted.SelectMany((str, index) => index % 2 == 0 ? str.Split(',') : new[] { str }); 
splitted = splitted.Where(str => !string.IsNullOrWhiteSpace(str)).Select(str => str.Trim());