【问题标题】:C# split comma separated valuesC#拆分逗号分隔值
【发布时间】:2013-12-20 10:12:08
【问题描述】:

如何将逗号分隔的字符串与也可以包含逗号的带引号的字符串分开?

输入示例

John, Doe, "Sid, Nency", Smith

预期输出

  • 约翰
  • 能源部
  • 席德,南希
  • 史密斯

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

那么拆分此类字符串的最佳方法是什么?

【问题讨论】:

  • 看起来您正在处理 CSV 输入?如果是这样,使用 CSV 库 - 有很多好的,它会为您省去很多痛苦!如果不是,请澄清您的问题以解释为什么 CSV 库不适合...
  • 不,它不是 CSV 文档。只是一个字符串
  • RB,如果你能告诉我我会很高兴,我如何使用 Csv Lib 来处理这个问题
  • 一种 Hackie 方法是先拆分 ",然后将备用字符串(在获得的数组中)拆分为 ,
  • Perl 解决方案在这里(因为你把标签放回去了):stackoverflow.com/questions/2459729/…

标签: c# .net regex csv


【解决方案1】:

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

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

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

ideone demo

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

然后只是修剪结果。

【讨论】:

    【解决方案2】:

    只需遍历您的字符串。当你浏览你的字符串时,请保持跟踪
    如果你在一个“块”中。如果您是 - 不要将逗号视为
    逗号(作为分隔符)。否则请照此处理。很简单
    算法,我自己写。当你遇到第一个“你进入
    一个块。当你遇到 next " 时,你结束了你原来的那个块,依此类推。
    所以你可以通过你的字符串来做到这一点。

    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 + "|");
            }
    
        }
    
    
    
    }
    

    【讨论】:

    • @AndreiMikhalevich 好的,我发布了一些代码作为说明。
    【解决方案3】:

    我在我的 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
    

    【讨论】:

      【解决方案4】:

      如果你觉得正则表达式太复杂,你可以这样做:

      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());
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-11-06
        • 1970-01-01
        • 1970-01-01
        • 2018-12-25
        • 2011-07-26
        • 2015-04-01
        相关资源
        最近更新 更多