C#split逗号分隔值

时间:2013-12-20 10:12:09

标签: c# .net regex csv

如何将逗号分隔的字符串拆分为带引号的字符串?

示例输入

John, Doe, "Sid, Nency", Smith

预期输出

  • 约翰
  • Doe的
  • Sid,Nency
  • 史密斯

用逗号分割是好的,但我要求允许使用像“Sid,Nency”这样的字符串。我试图使用正则表达式来分割这些值。正则表达式",(?=([^\"]*\"[^\"]*\")*[^\"]*$)"来自Java问题,它对我的​​.NET代码不起作用。它将一些字符串加倍,找到额外的结果等。

那么分割这些字符串的最佳方法是什么?

4 个答案:

答案 0 :(得分:4)

这是因为捕获组。只需将其变为非捕获组:

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

捕获组将结果中包含捕获的部分。

ideone demo

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

只是修剪结果。

答案 1 :(得分: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 + "|");
        }

    }



}

答案 2 :(得分:0)

我在Csv Parser类中使用以下代码来实现此目的:

    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

答案 3 :(得分: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());