Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#处理CSV文件_C#_.net_File_Csv - Fatal编程技术网

C#处理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>()

我有以下带有此标题的CSV文件:

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.
}