C#中拆分含双引号的逗号分隔字符串问题及实现代码
解决带引号包含分隔符的CSV字符串拆分问题
我来帮你搞定这个CSV字符串拆分的问题!你的需求很明确:要把"1,2-Benzene-d4",36925,10.483,0.95,,拆分成包含指定元素的数组,但当前的实现逻辑有一些问题,我们一步步来修正。
先说说你现有代码的问题
你的函数思路是尝试区分带引号的开头,但忽略了几个关键场景:
- 没有处理引号内部的分隔符(比如
"1,2-Benzene-d4"里的逗号),直接用"+分隔符的方式拆分,会把这个字段拆错 - 一开始就添加了一个空字符串
arrayOfFields.Add("");,这会导致结果数组多出来一个不必要的空元素 - 对引号的处理太粗暴,直接替换所有引号并Trim,没有考虑完整的引号包裹逻辑
推荐的两种解决方案
方案1:用.NET内置的TextFieldParser(最省心)
.NET其实自带了专门处理分隔符文本的类TextFieldParser,它能自动识别带引号的字段,完美解决你的问题。只需要引用Microsoft.VisualBasic程序集(别担心,这个程序集是.NET官方的,完全可靠):
using Microsoft.VisualBasic.FileIO; using System.IO; public static string[] SplitDelimitedText(string myString, string delimiter, out int numberOfFields) { numberOfFields = 0; if (string.IsNullOrEmpty(myString)) return Array.Empty<string>(); using var stringReader = new StringReader(myString); using var parser = new TextFieldParser(stringReader); parser.Delimiters = new[] { delimiter }; parser.HasFieldsEnclosedInQuotes = true; // 核心配置:开启引号字段识别 try { var fields = parser.ReadFields() ?? Array.Empty<string>(); numberOfFields = fields.Length; return fields; } catch { throw; } }
用你的测试字符串跑这个函数,直接就能得到你想要的结果:
str[0] = "1,2-Benzene-d4"str[1] = "36925"str[2] = "10.483"str[3] = "0.95"str[4] = ""
方案2:手动实现解析逻辑(不想引用额外程序集的话)
如果不想加Microsoft.VisualBasic的引用,我们可以自己写一个简单的状态机来解析,处理引号的开启/关闭,以及分隔符的判断:
public static string[] SplitDelimitedText(string myString, string delimiter, out int numberOfFields) { numberOfFields = 0; if (string.IsNullOrEmpty(myString)) return Array.Empty<string>(); var fields = new List<string>(); var currentField = new StringBuilder(); bool isInQuotes = false; char delimiterChar = delimiter[0]; // 假设分隔符是单个字符,符合常规CSV场景 foreach (char c in myString) { if (c == '"') { // 切换引号状态,同时处理CSV里用""转义"的情况 if (isInQuotes && currentField.Length > 0 && currentField[currentField.Length - 1] == '"') { currentField.Append('"'); // 遇到"",添加一个"到字段 continue; } isInQuotes = !isInQuotes; } else if (c == delimiterChar && !isInQuotes) { // 遇到分隔符且不在引号内,结束当前字段 fields.Add(currentField.ToString()); currentField.Clear(); } else { currentField.Append(c); } } // 别忘了添加最后一个字段 fields.Add(currentField.ToString()); numberOfFields = fields.Count; return fields.ToArray(); }
这个手动实现的逻辑也能完美处理你的测试用例,同时支持CSV里的引号转义(比如"He said ""Hello""",World会拆成["He said "Hello"", "World"])。
测试验证
把你的输入字符串"1,2-Benzene-d4",36925,10.483,0.95,,代入任意一个方案,都能得到你期望的拆分结果。
内容的提问来源于stack exchange,提问作者Kiran Desai
相关产品推荐
相关产品推荐

