C#处理CSV文件
我有以下带有此标题的CSV文件:C#处理CSV文件,c#,.net,file,csv,C#,.net,File,Csv,我有以下带有此标题的CSV文件: AccountOwnerEmail PartnerName注册ID客户许可计划国家/地区文化问题 用这样的句子: v-dakash@catalysis.com“嘿”?测试仪,12345789,“催化”,有限责任公司,企业6测试等 我有一种方法将行分隔为相应的列: var columns = columnsRegex.Matches(line) .Cast<Match>()
AccountOwnerEmail PartnerName注册ID客户许可计划国家/地区文化问题
用这样的句子:
v-dakash@catalysis.com“嘿”?测试仪,12345789,“催化”,有限责任公司,企业6测试等
我有一种方法将行分隔为相应的列:
var columns = columnsRegex.Matches(line)
.Cast<Match>()
.Select(m=> m.Value.Trim('\"', '\'', ' ', '\t'))
.ToList();
我这里的问题是,例如,PartnerName
内容被分成3列,如“
“嘿”
和“?Tester”
我知道CSV用另一个双引号转义双引号。我已经查看了另一篇类似的帖子,其中建议添加对Microsoft.VisualBasic
的引用,但这对我不起作用。有没有其他方法可以正确处理CSV内容?编辑:添加了另一种解析器方法、固定行和测试解析输出
我想说,你的正则表达式模式是错误的。它不允许在“
前缀值中使用(双重)”
字符。同样的问题也适用于”
internal static class Program
{
private const string wrongLine = "v-dakash@catalysis.com,\"HEY\"? Tester, 12345789,\"Catalysis\", LLC., Enterprise 6 TEST, etc,etc ,etc";
private const string fixedLine = "v-dakash@catalysis.com,\"\"\"HEY\"\"? Tester\", 12345789,\"Catalysis\", LLC., Enterprise 6 TEST, etc,etc ,etc";
private static readonly Regex wrongPattern = new Regex("\"[^\"]*\"|'[^']*'|[^,;]+");
private static readonly Regex fixedPattern = new Regex("((?:\"((?:[^\"]|\"\")*)\")|(?:'((?:[^']|'')*)')|([^,;]*))(?:[,;]|$)");
private static void Main()
{
Console.WriteLine("*** Wrong line: ***");
Console.WriteLine();
Parse(wrongLine);
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("*** Fixed line: ***");
Console.WriteLine();
Parse(fixedLine);
}
private static void Parse(string line)
{
Console.WriteLine("--- [Original Regex] ---");
var matches = wrongPattern.Matches(line);
for (int i = 0; i < matches.Count; i++)
{
Console.WriteLine("'" + matches[i].Value + "'");
}
Console.WriteLine();
Console.WriteLine("--- [Fixed Regex] ---");
Console.WriteLine();
matches = fixedPattern.Matches(line);
for (int i = 0; i < matches.Count; i++)
{
Console.WriteLine("'" + GetValue(matches[i]) + "'");
}
Console.WriteLine();
Console.WriteLine("--- [Correct(?) parser] ---");
Console.WriteLine();
var position = 0;
while (position < line.Length)
{
var value = GetValue(line, ref position);
Console.WriteLine("'" + value + "'");
}
}
private static string GetValue(Match match)
{
if (!string.IsNullOrEmpty(match.Groups[2].Value))
{
return (match.Groups[2].Value.Replace("\"\"", "\""));
}
if (!string.IsNullOrEmpty(match.Groups[3].Value))
{
return (match.Groups[3].Value.Replace("''", "'"));
}
return (match.Groups[4].Value.Replace("''", "'"));
}
private static string GetValue(string line, ref int position)
{
string value;
char? prefix;
string endWith;
switch (line[position])
{
case '\'':
case '\"':
prefix = line[position];
endWith = prefix + ",";
position++;
break;
default:
prefix = null;
endWith = ",";
break;
}
var endPosition = line.IndexOf(endWith, position);
if (endPosition < 0 && prefix.HasValue)
{
if (line[line.Length - 1] == prefix.Value)
{
value = line.Substring(position, line.Length - 1 - position);
position = line.Length;
return Fixprefix(value, prefix.Value.ToString());
}
position--;
endPosition = line.IndexOf(',', position);
}
if (endPosition < 0)
{
value = line.Substring(position);
position = line.Length;
return value;
}
if (prefix.HasValue)
{
value = line.Substring(position, endPosition - position);
position = endPosition + endWith.Length;
return Fixprefix(value, prefix.Value.ToString());
}
value = line.Substring(position, endPosition - position);
position = endPosition + endWith.Length;
return value;
}
private static string Fixprefix(string value, string prefix) => value.Replace(prefix + prefix, prefix);
}
我用它。这是一个解析CSV文档的非常好的库。使用nuget软件包:
Install-Package CsvHelper
可以找到文档
有多个.NET的CSV解析器(请参阅)。这不是CSV。用正则表达式解析它是正确的,字段名是^\w+:
,其他所有内容都是它的值。忽略标题(如果记录以某种方式被一个完整的空行从示例中分隔开,否则只需使用它来计算每个记录header.Split(“”).Length
)中的字段数。或者,一个简单的line.IndexOf(“:”)
在这种情况下也可以很好地工作…“像这样的行”不是这样的CSV@Richard如果它是一个实际的CSV文件,那么是。。。这本质上是一个文本文件。我编辑了文本以显示真正的CSV行。我认为问题不在于正则表达式,问题在于CSV添加了双引号以转义双引号,因此c#的读取方式类似于“嘿”?TEST“
@pedrodotnet:真正的问题(其中之一)是正则表达式。它不允许在“
前缀项值中使用”
字符(例如,“值为”“a”“”
将无法正确解析)。即使在我的示例中,也有两种可能的解析结果之一。(还有IMHO,不正确的一个。)但是这样解析(不正确的)字符串,它应该根据请求进行解析。新的正则表达式有一点帮助,现在不是将内容拆分到不同的列中,而是将“Hey?Tester”
解析为“Hey\”Tester\“
即使在正确的示例中?什么是不正确的行?例如,这行v-dakash@catalysis.com“嘿”?测试员,12345789,“Catalystation”,LLC,Enterprise 6 TEST,等等等等,等等,等等,等等
值“嘿”?Tester
返回为\“Hey\”\?Tester“
我会尝试一下,让您知道我的问题是路径中的returnin非法字符因双引号而出错。我无法删除它们,我需要显示file@pedrodotnet你能用Excel打开你的文档吗?我感觉像你的“CSV”“文档格式不好。是的,它是一个Excel文件,我将Excel上传到我的解决方案来处理它。我使用了CSVHelper,非常好。”。我用简单的定制工具解决了所有的问题。我将/r/n图表固定在一列中,将一列解析为多列,等等@pedrodotnet这样做,将是最好的解决方案
*** Wrong line: ***
--- [Original Regex] ---
'v-dakash@catalysis.com'
'"HEY"'
'? Tester'
' 12345789'
'"Catalysis"'
' LLC.'
' Enterprise 6 TEST'
' etc'
'etc '
'etc'
--- [Fixed Regex] ---
'v-dakash@catalysis.com'
'"HEY"? Tester'
' 12345789'
'Catalysis'
' LLC.'
' Enterprise 6 TEST'
' etc'
'etc '
'etc'
''
--- [Correct(?) parser] ---
'v-dakash@catalysis.com'
'HEY"? Tester, 12345789,"Catalysis'
' LLC.'
' Enterprise 6 TEST'
' etc'
'etc '
'etc'
*** Fixed line: ***
--- [Original Regex] ---
'v-dakash@catalysis.com'
'""'
'"HEY"'
'"? Tester"'
' 12345789'
'"Catalysis"'
' LLC.'
' Enterprise 6 TEST'
' etc'
'etc '
'etc'
--- [Fixed Regex] ---
'v-dakash@catalysis.com'
'"HEY"? Tester'
' 12345789'
'Catalysis'
' LLC.'
' Enterprise 6 TEST'
' etc'
'etc '
'etc'
''
--- [Correct(?) parser] ---
'v-dakash@catalysis.com'
'"HEY"? Tester'
' 12345789'
'Catalysis'
' LLC.'
' Enterprise 6 TEST'
' etc'
'etc '
'etc'
Install-Package CsvHelper
var csv = new CsvReader( textReader );
var records = csv.GetRecords<MyCsvRecord>();
public class MyCsvRecord
{
public string AccountOwnerEmail { get; set; }
public string PartnerName { get; set; }
// etc.
}