c# - 用引号和不带引号的字符串拆分逗号分隔的字符串

标签 c# regex

<分区>

我有以下需要拆分的逗号分隔字符串。问题是某些内容在引号内并且包含不应在拆分中使用的逗号。

字符串:

111,222,"33,44,55",666,"77,88","99"

我想要输出:

111  
222  
33,44,55  
666  
77,88  
99  

我试过这个:

(?:,?)((?<=")[^"]+(?=")|[^",]+)   

但它读取“77,88”、“99”之间的逗号作为命中,我得到以下输出:

111  
222  
33,44,55  
666  
77,88  
,  
99  

最佳答案

根据您的需要,您可能无法使用 csv 解析器,并且实际上可能想要重新发明轮子!!

你可以用一些简单的正则表达式来做到这一点

(?:^|,)(\"(?:[^\"]+|\"\")*\"|[^,]*)

这将执行以下操作:

(?:^|,) = 匹配表达式“行或字符串的开头 ,

(\"(?:[^\"]+|\"\")*\"|[^,]*) = 一个编号的捕获组,这将在 2 个选项之间进行选择:

  1. 引号内的内容
  2. 逗号之间的东西

这应该会为您提供所需的输出。

C# 示例代码

 static Regex csvSplit = new Regex("(?:^|,)(\"(?:[^\"]+|\"\")*\"|[^,]*)", RegexOptions.Compiled);

public static string[] SplitCSV(string input)
{

  List<string> list = new List<string>();
  string curr = null;
  foreach (Match match in csvSplit.Matches(input))
  {        
    curr = match.Value;
    if (0 == curr.Length)
    {
      list.Add("");
    }

    list.Add(curr.TrimStart(','));
  }

  return list.ToArray();
}

private void button1_Click(object sender, RoutedEventArgs e)
{
    Console.WriteLine(SplitCSV("111,222,\"33,44,55\",666,\"77,88\",\"99\""));
}

警告 根据@MrE 的评论 - 如果流氓换行符出现在格式错误的 csv 文件中并且您最终得到不均匀(“字符串”),您将得到灾难性的回溯( https://www.regular-expressions.info/catastrophic.html )在你的正则表达式中,你的系统可能会崩溃(就像我们的生产系统那样)。可以很容易地在 Visual Studio 中复制,正如我发现的那样会使它崩溃。一个简单的 try/catch 也不会解决这个问题。

你应该使用:

(?:^|,)(\"(?:[^\"])*\"|[^,]*)

代替

关于c# - 用引号和不带引号的字符串拆分逗号分隔的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3776458/

相关文章:

c# - WPF - 将 Datagrid Items.Count 绑定(bind)到自定义控件标签

c# - 在 WCF 中调试服务时,发生元数据交换错误

c# - 尝试创建一个自定义 cmdlet,它将 [ref] 作为参数

Ruby gsub 匹配串联

regex - Shell - 如何处理 find -regex?

已声明变量的 C# 开关案例行为

c# - 根据属性显示/隐藏网格行?

ruby - 使用转义字符解析定界文本

javascript - 匹配任何不以零结尾的数字的正则表达式

java - 在 Java 中使用分隔符逗号在嵌套大括号中拆分字符串