C# 如何在 csvline.split(',') 之前从逗号分隔的 csv 文件中的特定行中删除多余的逗号

C# How to remove extra comma form a specific line in a comma delimited csv file before the csvline.split(',')

问候语 我之前曾寻求过有关解析的帮助,并且帮助很大。 几天后,我再次需要帮助找到一个合乎逻辑的方法来解决这个问题。

下面是我正在解析的行

 5/13/2019,"PHONE SERVICE,/GUIA:54 REF:0000000005556 CIE:041",872,,

这一行 -->(5/13/2019,"PHONE SERVICE,/GUIA:54 REF:0000000005556 CIE:041",872,) <-- 在服务之后,这是使我的代码抛出错误的额外逗号

这是代码

      class Program
        {
         static void Main(string[] args)
        {
        ParserCSV();
        Console.WriteLine("...");
        Console.ReadLine();
    }


    private static void ParserCSV()
    {

        Console.WriteLine("Parsing the csv file");

        List<clsEstadoCuenta> resp = new List<clsEstadoCuenta>();
        var csvLines = File.ReadAllLines("D:\ztemp\New 
        folder\ParserTestMX.csv");
        clsEstadoCuenta nR = new clsEstadoCuenta();


        foreach (var lineas in csvLines.Skip(1))
        {

            var campos = lineas.Split(',');

            campos[3] = campos[2] + campos[3];
            campos[1] = campos[1] + campos[2];
            string nuevaLinea = "";
            for (int i = 3; i < campos.Count(); i++)
            {
                if (!string.IsNullOrEmpty(campos[i]))
                {
                    if (campos[i][0] == '\"' || campos[i][0] == '"')
                    {
                        campos[i] = campos[i] + campos[i + 1];
                        campos[i + 1] = "";
                        campos[i] = campos[i].Replace("\"", "");
                    }
                }
                nuevaLinea += $"{campos[i]} \t";
            }
            //campos[3] = campos[2];
            var tmpFecha = campos[0].Split('/');
            nR.FechaTransaccion = new 
            DateTime(Convert.ToInt32(tmpFecha[2]), 
            Convert.ToInt32(tmpFecha[0]), Convert.ToInt32(tmpFecha[1]));
            var tmpDesc = campos[1].Split('/');
            nR.Descripcion = (String.IsNullOrEmpty(tmpDesc[0])) ? "" : 
            tmpDesc[0];
            nR.Referencia = (String.IsNullOrEmpty(tmpDesc[1])) ? "" : 
             tmpDesc[1];

            nR.Debito = (String.IsNullOrEmpty(campos[3])) ? 0 : 
             Convert.ToDouble(campos[3]);
            nR.Credito = (String.IsNullOrEmpty(campos[4])) ? 0 : 
             Convert.ToDouble(campos[4]);

            resp.Add(nR);
            if (nR.FechaTransaccion==null)
            {
                break;
            }



            }

         Console.WriteLine("Parsing has ended, we have {0} rows \n", 
         resp.Count);
         foreach (var item in resp)
         {
            Console.WriteLine($"{item.FechaTransaccion} |  
          {item.Descripcion} | {item.Referencia}|{item.Debito}| 
          {item.Credito} ");
         }


       }


    class clsEstadoCuenta
    {
        private string _NumeroCuenta;

        public string NumeroCuenta
        {
            get { return _NumeroCuenta; }
            set { _NumeroCuenta = value; }
        }
        private int _CodigoPais;

        public int CodigoPais
        {
            get { return _CodigoPais; }
            set { _CodigoPais = value; }
        }

        private string _Banco;

        public string Banco
        {
            get { return _Banco; }
            set { _Banco = value; }
        }

        private string _Moneda;

        public string Moneda
        {
            get { return _Moneda; }
            set { _Moneda = value; }
        }

        private double _TasaCambio;

        public double TasaCambio
        {
            get { return _TasaCambio; }
            set { _TasaCambio = value; }
        }

        private double _Debito;

        public double Debito
        {
            get { return _Debito; }
            set { _Debito = value; }
        }

        private double _Credito;

        public double Credito
        {
            get { return _Credito; }
            set { _Credito = value; }
        }

        private DateTime _FechaTrasaccion;

        public DateTime FechaTransaccion
        {
            get { return _FechaTrasaccion; }
            set { _FechaTrasaccion = value; }
        }

        private string _Payee;

        public string Payee
        {
            get { return _Payee; }
            set { _Payee = value; }
        }

        private string _Descripcion;

        public string Descripcion
        {
            get { return _Descripcion; }
            set { _Descripcion = value; }
        }

        private string _Referencia;

        public string Referencia
        {
            get { return _Referencia; }
            set { _Referencia = value; }
        }

        private string _CodigoBancario;

        public string CodigoBancario
        {
            get { return _CodigoBancario; }
            set { _CodigoBancario = value; }
        }

        private string _Categoria;

        public string Categoria
        {
            get { return _Categoria; }
            set { _Categoria = value; }
        }

        private string _Sector;

        public string Sector
        {
            get { return _Sector; }
            set { _Sector = value; }
        }

        private double _ValorLocal;

        public double ValorLocal
        {
            get
            {
                _ValorLocal = Credito - Debito;
                return _ValorLocal;
            }
            //set { _ValorLocal = value; }
        }

        private double _ValorDolares;

        public double ValorDolares
        {
            get
            {
                _ValorDolares = ValorLocal / TasaCambio;
                return _ValorDolares;
            }
            // set { _ValorDolares = value; }
        }

        private string _NombreEmpresa;

        public string NombreEmpresa
        {
            get { return _NombreEmpresa; }
            set { _NombreEmpresa = value; }
        }

      }
    }
   }

请帮忙,我一直在努力寻找忽略该行逗号的最佳逻辑方法。但我不能,因为在我可以做任何事情之前,线路已经分开了

迭代每一行并使用

解析它
string currentRow = eachLineToParse;
Regex CSVParser = new Regex(",(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))");
String[] rowish = CSVParser.Split(currentRow);

rowish 应该 return 一个包含您的值的数组。

在多出逗号的行中,包含逗号的值用引号引起来。

 5/13/2019,SPEI ENVIADO SANTANDER/03GASOLINA MAYO (3),"1,000.00",,
 5/13/2019,"TELEFONOS DE MEXICO,/GUIA:54 REF:0000000005556 CIE:041",872,,
           ^                                                      ^

这是一种标准方式,用于指示引号内的任何内容都是单个值,不应根据其中的任何逗号进行拆分。

这意味着您需要编写基于逗号拆分的代码,除非它们位于引号内。这样做……不要。只需使用一个现有的库来为您处理。试试 CsvHelper.

首先定义一个class,定义每一行包含的数据:

public class Data
{ 
    [Name("D?")]
    public DateTime Date { get; set; }

    [Name("Concepto / Referencia")]
    public string Conceptio { get; set; }

    [Name("cargo")]
    public string Cargo { get; set; }

    [Name("Abono")]
    public string Abono { get; set; }
}

如果 属性 名称与列 header 匹配,我们不需要 CsvHelper.Configuration.Attributes.NameAttribute,但我们不能命名 属性 D?所以我们需要属性。

那么读取它的代码如下所示:

public Data[] ReadDate(string fileName)
{
    using (var file = File.OpenText(fileName))
    {
        using (var reader = new CsvReader(file))
        {
            return reader.GetRecords<Data>().ToArray();
        }
    }
}

现在我们已经将 CSV 数据解析为 Data 数组,我们可以用它做任何我们想做的事。

我什至没有为引号添加任何特殊处理,因为这是 CsvHelper 的默认行为。它不会尝试在引号内拆分值。如果需要,您可以指定不同的字符,但在这种情况下我们都准备好了。