从技术上讲,您正在查看的示例不是有效的 CSV 格式文件。基本上,提供文件的人以非标准方式使用了文本限定符符号 - 双引号 "。使用它的传统方式是这样的:
123,"Sue said, ""Hi, this is a test!""",2012-08-15
此语句应解析为:
Assert.AreEqual(line.Length, 3);
Assert.AreEqual(line[0], @"123");
Assert.AreEqual(line[1], @"Sue said, ""Hi, this is a test!""");
Assert.AreEqual(line[2], @"2012-08-15");
根据我看到的标准,从您的问题中提供的示例 CSV 来看,正确的处理基本上应该将引号视为字符串中的常规字符,而不是文本限定符。这就是我如何解释你的台词——如果我错了,请告诉我!
Assert.AreEqual(line.Length, 6);
Assert.AreEqual(line[0], @"30: ""NY""");
Assert.AreEqual(line[1], @" 41: ""JOHN S.""");
Assert.AreEqual(line[2], @" 36: ""HAMPTON""");
Assert.AreEqual(line[3], @" 42: ""123 Road Street");
Assert.AreEqual(line[4], @" NY""");
Assert.AreEqual(line[5], @" 68: ""Y""");
我想 FileHelper 正在破坏,因为它无法确定文本是文本限定的还是正确分隔的。你最好使用自定义代码来处理这个;Cuong Le 提供的解决方案似乎适合您的解决方案。
作为参考,我的 C# CSV 库在这里:https ://code.google.com/p/csharp-csv-reader/
编辑:为了好玩,我想知道是否可以使用正则表达式对此进行解码。您的数据的格式是一致的,即使它不是严格的 CSV,所以也许这对您的工具箱来说是别的东西:
String mystring = @"30: ""NY"", 41: ""JOHN S."", 36: ""HAMPTON"", 42: ""123 Road Street, NY"", 68: ""Y""
20: ""STEVE"", 12: ""JONES"", 96: ""1600 PENNSYLVANIA AVE, NW""
30: ""NY"", 41: ""JOHN S."", 36: ""HAMPTON"", 42: ""123 Road Street, NY"", 68: ""Y"", 40: 12345";
Regex r = new Regex(@"(?<id>\d*): (""(?<field>[^""]*)""|(?<field>[\d]*))");
MatchCollection mc = r.Matches(mystring);
foreach (Match m in mc) {
Console.WriteLine("{0}: {1}", m.Groups["id"], m.Groups["field"]);
}
基本上,正则表达式通过查找两个十进制数字,后跟冒号 - 空格 - 双引号来工作。然后它会查找所有文本,直到它到达另一个双引号。根据我的测试,这也会为您在问题中描述的两条测试线产生正确的匹配。
如果我的正则表达式不太正确,这里有一个漂亮的在线正则表达式测试器:http: //gskinner.com/RegExr/ - 尝试将数据复制并粘贴到搜索区域,然后使用这个正则表达式字符串作为起点:
(?<id>\d*): ("(?<field>[^"]*)"|(?<field>[\d]*))
EDIT2:我修复了正则表达式,还考虑了您在下面的评论中引用的“40:12345”值。它现在可以正确检测所有示例中的所有字段。
EDIT3:从另一个请求,这个正则表达式现在支持冒号前的无限长度数字。以下是正则表达式如何工作的快速解释:
(?<id>\d*)
- 第一个块称为捕获组 - 捕获组用括号括起来。它尝试捕获*
十进制数字 ( ) 的重复字符串 ( \d
) 并将其命名为“id” ( ?<id>
)。
:
- 匹配记录之间的冒号空格。
"(?<field>[^"]*)"
- 查找开头的引号,然后查找除引号 ( ) 之外的大量字符[^"]
,并以另一个引号结尾。将结果保存在“字段”中。
(?<field>[\d]*)
- 查找任意数量的十进制数字并将结果保存在“字段”中。请注意,某些正则表达式引擎不支持拥有两个具有相同名称的捕获组;您可能必须调用一个“field1”和另一个“field2”。