读取包含货币的逗号分隔 CSV
Reading a comma delimited CSV that contains currency
下面是从逗号分隔的 CSV 文件中读取的内容。
每行 [2] 中的第三个字段货币字段是问题所在。
我需要在逗号处拆分字段,但货币字段有时可能很大并且也有它们。
如何拆分包含货币的逗号分隔的 csv 文件??
csv 始终保持每行 5 个字段一致。
下面示例中的第一行有效,但第二行会导致问题。
3,09:29 pm,€20.00,测试,测试
1,02:55 am,€10,000.00,测试,测试
StreamReader fileIn = new StreamReader(path);
//Read the file
while (!fileIn.EndOfStream)
{
String line = fileIn.ReadLine();
String[] pieces = line.Split(',');
csvComplete cEve = new csvComplete (pieces[0], pieces[1], pieces[2], pieces[3], pieces[4]);// assign to class cEve
entries.Add(cEve);
}
如有任何链接或建议,我们将不胜感激。
我之前也遇到过类似的问题,于是求助于Microsoft.VisualBasic.FileIO.TextFieldParser
。在你的情况下,试试这个:
using(TextFieldParser parser = new TextFieldParser(new StreamReader(path)){
parser.Delimiters = new string [] {","};
while(true){
String[] pieces = parser.ReadFields();
if(pieces == null)
break;
csvComplete cEve = new csvComplete (pieces[0], pieces[1], pieces[2], pieces[3], pieces[4]);// assign to class cEve
entries.Add(cEve);
}
}
可以找到更多信息 here。
这是一个技巧:
//Read the file
while (!fileIn.EndOfStream)
{
String line = fileIn.ReadLine();
String[] pieces = line.Split(',');
if(pieces.length > 5){
String[] newPieces = new String[5];
newPieces[0] = pieces[0];
newPieces[1] = pieces[1];
String currency = "";
for(int i = 2; i < pieces.length - 2; i++){
if(i == pieces.length -3)
currency += pieces[i];
else{
currency += pieces[i] + ",";
}
}
newPieces[2] = currency;
newPieces[3] = pieces[pieces.length-2];
newPieces[4] = pieces[pieces.length-1];
csvComplete cEve = new csvComplete (newPieces[0], newPieces[1], newPieces[2], newPieces[3], newPieces[4]);// assign to class cEve
entries.Add(cEve);
}
else{
csvComplete cEve = new csvComplete (pieces[0], pieces[1], pieces[2], pieces[3], pieces[4]);// assign to class cEve
entries.Add(cEve);
}
}
这应该考虑更大的货币(万亿欧元会有更多逗号)。
希望对您有所帮助!
暴力破解:
StreamReader fileIn = new StreamReader(path);
//Read the file
while (!fileIn.EndOfStream)
{
String line = fileIn.ReadLine();
String[] pieces = line.Split(',');
if (pieces.Length == 5)
{
// Exactly 5 fields.
csvComplete cEve = new csvComplete (pieces[0], pieces[1], pieces[2], pieces[3], pieces[4]);// assign to class cEve
}
else if (pieces.Length == 6)
{
// Exactly 6 fields. We'll assume fields 1 and 2 should combine for currency string.
csvComplete cEve = new csvComplete (pieces[0], pieces[1] + "," + pieces[2], pieces[3], pieces[4], pieces[5], pieces[6]);// assign to class cEve
}
else
{
// ?
}
entries.Add(cEve);
}
如果行长度是动态的
我对这个问题的解决方案是实现在数组的一个成员和基数“.”中查找欧元符号“€”的逻辑。在随后的成员中。如果满足这个条件,那么你就可以认为你遇到了你所说的特殊情况。
如果我们知道一行应该有多少字段
或者,如果您知道每个数组(CSV 的每一行上的字段)中的成员数量应该始终相同,那么您的逻辑就会变得更简单。只需查找一个成员过多的数组。
以你的例子为例,我们假设每个数组应该恰好有五个成员:
0:索引/身份证号码
1: 子午线时间值
2:欧元货币金额
3: 测试数据1
4: 测试数据2
我们现在可以查找具有六个成员的数组并应用我们的业务逻辑:
String line = fileIn.ReadLine();
String[] pieces = line.Split(',');
if( pieces.Length == 6 )
{
pieces[2] = String.Concat(pieces[2], pieces[3]);
pieces[3] = pieces[4];
pieces[4] = pieces[5];
}
csvComplete cEve = new csvComplete (pieces[0], pieces[1], pieces[2], pieces[3], pieces[4]);// assign to class cEve
entries.Add(cEve);
轻量级解决方案
Has you can see I convert the comma inside the quotes in another character. And works for all the fields with the same case inside the string. You can put this snippet inside a method for reusability.
示例字符串:
40,3063,16,32,36,37,41,56,5,"$30,600,000.00",12/4/2017
string sRead = sr.ReadLine();
char[] srcTemp = sRead.ToCharArray();
for (int i = 0; i < srcTemp.Length - 1; i++)
{
if ((int)srcTemp[i] == 34)
{
int yCharnichart = 0;
for (int c = i + 1; c < srcTemp.Length - 1; c++)
{
if ((int)srcTemp[c] == 34) break;
if ((int)srcTemp[c] == 44) srcTemp[c] = (char)182;
yCharnichart++;
}
i += yCharnichart + 1;
}
}
StringBuilder sb = new StringBuilder();
sb.Append(srcTemp);
Result: 40,3063,16,32,36,37,41,56,5,"¶600¶000.00",12/4/2017
最后:再次将您选择的字符替换为逗号
BOLSA = arRead[9].Replace((char)182, (char)44)
下面是从逗号分隔的 CSV 文件中读取的内容。
每行 [2] 中的第三个字段货币字段是问题所在。 我需要在逗号处拆分字段,但货币字段有时可能很大并且也有它们。
如何拆分包含货币的逗号分隔的 csv 文件??
csv 始终保持每行 5 个字段一致。
下面示例中的第一行有效,但第二行会导致问题。
3,09:29 pm,€20.00,测试,测试
1,02:55 am,€10,000.00,测试,测试
StreamReader fileIn = new StreamReader(path);
//Read the file
while (!fileIn.EndOfStream)
{
String line = fileIn.ReadLine();
String[] pieces = line.Split(',');
csvComplete cEve = new csvComplete (pieces[0], pieces[1], pieces[2], pieces[3], pieces[4]);// assign to class cEve
entries.Add(cEve);
}
如有任何链接或建议,我们将不胜感激。
我之前也遇到过类似的问题,于是求助于Microsoft.VisualBasic.FileIO.TextFieldParser
。在你的情况下,试试这个:
using(TextFieldParser parser = new TextFieldParser(new StreamReader(path)){
parser.Delimiters = new string [] {","};
while(true){
String[] pieces = parser.ReadFields();
if(pieces == null)
break;
csvComplete cEve = new csvComplete (pieces[0], pieces[1], pieces[2], pieces[3], pieces[4]);// assign to class cEve
entries.Add(cEve);
}
}
可以找到更多信息 here。
这是一个技巧:
//Read the file
while (!fileIn.EndOfStream)
{
String line = fileIn.ReadLine();
String[] pieces = line.Split(',');
if(pieces.length > 5){
String[] newPieces = new String[5];
newPieces[0] = pieces[0];
newPieces[1] = pieces[1];
String currency = "";
for(int i = 2; i < pieces.length - 2; i++){
if(i == pieces.length -3)
currency += pieces[i];
else{
currency += pieces[i] + ",";
}
}
newPieces[2] = currency;
newPieces[3] = pieces[pieces.length-2];
newPieces[4] = pieces[pieces.length-1];
csvComplete cEve = new csvComplete (newPieces[0], newPieces[1], newPieces[2], newPieces[3], newPieces[4]);// assign to class cEve
entries.Add(cEve);
}
else{
csvComplete cEve = new csvComplete (pieces[0], pieces[1], pieces[2], pieces[3], pieces[4]);// assign to class cEve
entries.Add(cEve);
}
}
这应该考虑更大的货币(万亿欧元会有更多逗号)。
希望对您有所帮助!
暴力破解:
StreamReader fileIn = new StreamReader(path);
//Read the file
while (!fileIn.EndOfStream)
{
String line = fileIn.ReadLine();
String[] pieces = line.Split(',');
if (pieces.Length == 5)
{
// Exactly 5 fields.
csvComplete cEve = new csvComplete (pieces[0], pieces[1], pieces[2], pieces[3], pieces[4]);// assign to class cEve
}
else if (pieces.Length == 6)
{
// Exactly 6 fields. We'll assume fields 1 and 2 should combine for currency string.
csvComplete cEve = new csvComplete (pieces[0], pieces[1] + "," + pieces[2], pieces[3], pieces[4], pieces[5], pieces[6]);// assign to class cEve
}
else
{
// ?
}
entries.Add(cEve);
}
如果行长度是动态的
我对这个问题的解决方案是实现在数组的一个成员和基数“.”中查找欧元符号“€”的逻辑。在随后的成员中。如果满足这个条件,那么你就可以认为你遇到了你所说的特殊情况。
如果我们知道一行应该有多少字段
或者,如果您知道每个数组(CSV 的每一行上的字段)中的成员数量应该始终相同,那么您的逻辑就会变得更简单。只需查找一个成员过多的数组。
以你的例子为例,我们假设每个数组应该恰好有五个成员:
0:索引/身份证号码
1: 子午线时间值
2:欧元货币金额
3: 测试数据1
4: 测试数据2
我们现在可以查找具有六个成员的数组并应用我们的业务逻辑:
String line = fileIn.ReadLine();
String[] pieces = line.Split(',');
if( pieces.Length == 6 )
{
pieces[2] = String.Concat(pieces[2], pieces[3]);
pieces[3] = pieces[4];
pieces[4] = pieces[5];
}
csvComplete cEve = new csvComplete (pieces[0], pieces[1], pieces[2], pieces[3], pieces[4]);// assign to class cEve
entries.Add(cEve);
轻量级解决方案
Has you can see I convert the comma inside the quotes in another character. And works for all the fields with the same case inside the string. You can put this snippet inside a method for reusability.
示例字符串: 40,3063,16,32,36,37,41,56,5,"$30,600,000.00",12/4/2017
string sRead = sr.ReadLine();
char[] srcTemp = sRead.ToCharArray();
for (int i = 0; i < srcTemp.Length - 1; i++)
{
if ((int)srcTemp[i] == 34)
{
int yCharnichart = 0;
for (int c = i + 1; c < srcTemp.Length - 1; c++)
{
if ((int)srcTemp[c] == 34) break;
if ((int)srcTemp[c] == 44) srcTemp[c] = (char)182;
yCharnichart++;
}
i += yCharnichart + 1;
}
}
StringBuilder sb = new StringBuilder();
sb.Append(srcTemp);
Result: 40,3063,16,32,36,37,41,56,5,"¶600¶000.00",12/4/2017
最后:再次将您选择的字符替换为逗号
BOLSA = arRead[9].Replace((char)182, (char)44)