我想使用Split
函数分割文本:
string str = "ZBEE10364,\"Cobler, CHARLOTTE J\",Whiskey,,Brandy,0:00:00,20110912,CHECK,2918,117.33,1,117.33,0,EDM0,Yu789";
string[] strArr = str.Split(',');
此工作正常,但"Cober
和"CHARLOTTE
位于不同的记录中。我不希望这样。它是一个CSV文件,当我使用Excel打开它时,它可以很好地工作。
Cobler, CHARLOTTE J
出现在一个列中。我该如何解决这个问题?
答案 0 :(得分:3)
因为您要忽略引号之间的记录中的,
,所以执行此操作的唯一方法是解析该行。
使用布尔值循环遍历字符串(如果在引号之间,则为true),然后手工构建列表/数组,仅在布尔值为false时生成新项。
正如安德烈亚斯在评论中指出的那样,这个问题有完整的来源:
答案 1 :(得分:2)
可能有点矫枉过正,但JET的OLE DB提供程序也可以读取CSV文件,还可以为每列提供正确类型的数据。示例用于此question。
如果你想手工解析它(应该是可行的),你可以参考CSV上的维基百科article,其中详细说明了语法。
答案 2 :(得分:1)
这个辅助方法可以解决这个问题:
public static class StringSplitHelper{
public static string[] SplitNonQuoted(this string str, char separator){
if(string.IsNullOrEmpty(str)) return new string[]{};
if(separator == '\"') throw new ArgumentException("Separator cannot be a quotation mark", "separator");
List<string> fields = new List<string>();
bool inQuotes = false;
StringBuilder sb = new StringBuilder();
foreach(var c in str){
if(c == '\"')
{
inQuotes = !inQuotes;
}
else if(c == separator){
if(inQuotes) {
sb.Append(c);
}
else {
fields.Add(sb.ToString());
sb.Clear();
}
}
else{
sb.Append(c);
}
}
return fields.ToArray();
}
}
然后,而不是strArr = str.Split(',');
,
做strArr = str.SplitNonQuoted(this string str, ',');
答案 3 :(得分:0)
using System;
using System.Text;
using Microsoft.VisualBasic.FileIO; //Microsoft.VisualBasic.dll
using System.IO;
public class Sample {
static void Main(){
string str = "ZBEE10364,\"Cobler, CHARLOTTE J\",Whiskey,,Brandy,0:00:00,20110912,CHECK,2918,117.33,1,117.33,0,EDM0,Yu789";
string[] strArr = str.Split(',');
var reader = new StringReader(str);
using(var csvReader = new TextFieldParser(reader)){
csvReader.SetDelimiters(new string[] {","});
csvReader.HasFieldsEnclosedInQuotes = true;
strArr = csvReader.ReadFields();
}
//check print
foreach(var item in strArr){
Console.WriteLine("\"{0}\"",item);
}
}
}
<强> RESULT 强>
"ZBEE10364"
"Cobler, CHARLOTTE J"
"Whiskey"
""
"Brandy"
"0:00:00"
"20110912"
"CHECK"
"2918"
"117.33"
"1"
"117.33"
"0"
"EDM0"
"Yu789"