我不能成为第一个遇到此问题的人,但是经过数小时的搜索,Stack并没有找到答案。我有一个在csv文件目录下工作的SSIS脚本。该脚本折叠,弯曲和切割这些文件。执行查询,数据清理,保留一些数据,最后将一小集输出到另一个系统提取的csv文件。
其中一个文件的自由文本字段包含值:“ 20,000 BONUS POINTS”。这个字段(包含10k行的文件)是数十个类似文件中的一个,这是我似乎无法解决的问题。
请注意:我在C#和Regex方面都很弱。
csv样本集:
4121,6383,0,,,TRUE
4122,6384,0,"20,000 BONUS POINTS",,TRUE
4123,6385,,,,
4124,6386,0,,,TRUE
4125,6387,0,,,TRUE
4126,6388,0,,,TRUE
4127,6389,0,,,TRUE
4128,6390,0,,,TRUE
我发现了大量有关如何使用各种Regex模式进行解析的信息,但我注意到的是StreamReader.ReadLine()方法用双引号将完整的行括起来:
"4121,6383,0,,,TRUE"
这样的正则表达式Replace方法的输出:
s = Regex.Replace(line, @"[^\""]([^\""])*[^\""]", m => m.Value.Replace(",", ""));
看起来像这样:
412163830TRUE
和实际上包含双引号分隔的字符串的目标行最终看起来像:
“ 412263840 \” 20000奖励积分\“ TRUE”
(为了您的阅读乐趣)我的整个方法是:
string fileDirectory = "C:\\tmp\\Unzip\\";
string fullPath = "C:\\tmp\\Unzip\\test.csv";
string line = "";
//int count=0;
List<string> list = new List<string>();
try
{
//MessageBox.Show("inside Try Block");
string s = null;
StreamReader infile = new StreamReader(fullPath);
StreamWriter outfile = new StreamWriter(Path.Combine(fileDirectory, "output.csv"));
while ((line = infile.ReadLine()) != null)
{
//line.Substring(0,1).Substring(line.Length-1, 1);
System.Console.WriteLine(line);
Console.WriteLine(line);
line =
s = Regex.Replace(line, @"[^\""]([^\""])*[^\""]",
m => m.Value.Replace(",", ""));
System.Console.WriteLine(s);
list.Add(s);
}
foreach (string item in list)
{
outfile.WriteLine(item);
};
infile.Close();
outfile.Close();
//System.Console.WriteLine("There were {0} lines.", count);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
//another addition for TFS consumption
}
感谢阅读,如果您有有用的答案,请祝福您和您的神童后代!
mfc
编辑:要求是有效的csv文件输出。对于测试数据,它看起来像这样:
4121,6383,0 ,,, TRUE
4122,6384,0,“ 20000 BONUS POINTS” ,, TRUE
4123,6385 ,,,,
4124,6386,0 ,,, TRUE
4125,6387,0 ,,, TRUE
4126,6388,0 ,,, TRUE
4127,6389,0 ,,, TRUE
4128,6390,0 ,,, TRUE
答案 0 :(得分:1)
我建议像其他人建议的那样使用CSV阅读器库。
reloadData()
https://github.com/phatcher/CsvReader#getting-started
但是,如果您只想尝试快速又肮脏的事情。试试看。
如果我理解正确。您需要删除CSV文件每一行中双引号之间的逗号。这应该做到这一点。
Install-Package LumenWorksCsvReader
输出
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
public class Program
{
public static void Main()
{
string pattern = @"([""'])(?:(?=(\\?))\2.)*?\1";
List<string> lines = new List<string>();
lines.Add("4121,6383,0,,,TRUE");
lines.Add("4122,6384,0,\"20,000 BONUS POINTS\",,TRUE");
lines.Add("4123,6385,,,,");
lines.Add("4124,6386,0,,,TRUE");
lines.Add("4125,6387,0,,,TRUE");
lines.Add("4126,6388,0,,,TRUE");
lines.Add("4127,6389,0,,,TRUE");
lines.Add("4128,6390,0,,,TRUE");
StringBuilder sb = new StringBuilder();
foreach (var line in lines)
{
sb.Append(Regex.Replace(line, pattern, m => m.Value.Replace(",", ""))+"\n");
}
Console.WriteLine(sb.ToString());
}
}
答案 1 :(得分:1)
我没有尝试过很多行,但这是我的第一种方法:
namespace ConsoleTestApplication
{
class Program
{
static void Main(string[] args)
{
var before = "4122,6384,0,\"20,000 BONUS POINTS\",,TRUE";
var pattern = @"""[^""]*""";
var after = Regex.Replace(before, pattern, match => match.Value.Replace(",", ""));
Console.WriteLine(after);
}
}
}