我有以下带有此标头的CSV文件:
AccountOwnerEmail PartnerName EnrollmentID Customer LicensingProgram Country Culture Issue
带有这样的行:
v-dakash@catalysis.com,"HEY"? Tester, 12345789,"Catalysis", LLC., Enterprise 6 TEST, etc,etc ,etc
我有一种方法可以将行分成相应的列:
var columns = columnsRegex.Matches(line)
.Cast<Match>()
.Select(m=> m.Value.Trim('\"', '\'', ' ', '\t'))
.ToList();
这是columnsRegex
的定义:
private static Regex columnsRegex = new Regex("\"[^\"]*\"|'[^']*'|[^,;]+");
我的问题是,例如PartnerName
的内容被分成3列,例如""
"Hey"
和"?Tester"
我知道CSV转义了双引号和另一个双引号。而且我已经检查了与此类似的其他帖子,建议将其添加到Microsoft.VisualBasic
,但这对我不起作用。是否还有其他方法可以正确处理CSV内容?
答案 0 :(得分:2)
我使用CsvHelper。这是一个很好的库来解析CSV文档。使用nuget包:
Install-Package CsvHelper
可以找到文档here。
var csv = new CsvReader( textReader );
var records = csv.GetRecords<MyCsvRecord>();
MyCsvRecord
是您的CSV行,例如:
public class MyCsvRecord
{
public string AccountOwnerEmail { get; set; }
public string PartnerName { get; set; }
// etc.
}
答案 1 :(得分:1)
编辑:添加了另一种解析器方法,固定行和测试解析输出。
我会说,您的正则表达式模式是错误的。不允许在前缀"
中使用"
字符(加倍)。对于'
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);
}
“固定Regex
模式”仍然存在错误,但我将其保留为当前状态...
(说明您自己如何解决此问题。)
输出窗口:
*** 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'