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 的默认行为。它不会尝试在引号内拆分值。如果需要,您可以指定不同的字符,但在这种情况下我们都准备好了。
问候语 我之前曾寻求过有关解析的帮助,并且帮助很大。 几天后,我再次需要帮助找到一个合乎逻辑的方法来解决这个问题。
下面是我正在解析的行
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 的默认行为。它不会尝试在引号内拆分值。如果需要,您可以指定不同的字符,但在这种情况下我们都准备好了。