制表符分隔文件中的引号
Posted
技术标签:
【中文标题】制表符分隔文件中的引号【英文标题】:Quotes in tab-delimited file 【发布时间】:2011-01-26 09:59:48 【问题描述】:我有一个简单的应用程序,它打开一个制表符分隔的文本文件,并将该数据插入数据库。
我正在使用这个 CSV 阅读器来读取数据:http://www.codeproject.com/KB/database/CsvReader.aspx
而且一切正常!
现在我的客户在文件末尾添加了一个新字段,即“ClaimDescription”,并且在其中一些索赔描述中,数据中包含引号,例如:
“SUMISEI MARU NO 2”-日本海
这似乎让我的应用非常头疼。我得到一个如下所示的异常:
CSV 似乎在位置“181”的记录“1470”字段“26”附近已损坏。当前原始数据:...
在那个“原始数据”中,确实索赔描述字段显示了带有引号的数据。
我想知道是否有人以前遇到过这个问题,并且解决了它? 显然,我可以要求客户更改他们最初发送给我的数据,但这是他们用来生成制表符分隔文件的自动化过程;我宁愿把它作为最后的手段。
我想我可以事先使用标准 TextReader 打开文件,转义任何引号,将内容写回新文件,然后将该文件输入 CSV 阅读器。值得一提的是,这些制表符分隔文件的平均文件大小约为 40MB。
非常感谢任何帮助!
干杯,肖恩
【问题讨论】:
【参考方案1】:查看codeproject文章关于引号的评论:
http://www.codeproject.com/Messages/3382857/Re-Quotes-inside-of-the-Field.aspx
您需要在构造函数中指定要使用除 " 之外的另一个字符作为引号。
【讨论】:
+1 这是你需要做的。如果"
在 CSV 的其他地方用作引号字符,则文件只是不一致并且没有干净的解决方案【参考方案2】:
改用FileHelpers 库。它被广泛使用,可以处理带引号的字段或包含引号的字段。
【讨论】:
@Oded:问题不在于如何处理引用字段。它询问包含引号字符的 unquoted 字段。 @Luke:嗯。我开始不同意你的观点,因为没有真正的 CSV“标准”。不过,我确实找到了一个 RFC,看起来你是对的。 @T.E.D. - 有 CSV 的 RFC,但没有制表符分隔的 RFC。 好点。我想您可以说明它应该与 CSV RFC 相同,但使用制表符而不是逗号。不过,如果他们在 RFC 的某个地方说这样的话会更好。做到这一点并不难。【参考方案3】:我最近解决了一个类似的问题,尽管 CsvReader 在我的 TSV 文件的几行之外都可以正常工作,但最终解决我的问题是在 CsvReader
的构造函数中设置了一个 customDelimiter
public static void ParseTSV(string filepath)
using (CsvReader csvReader = new CsvReader(new StreamReader(filepath), true, '\t'))
//if that didn't work, passing unlikely characters into the other params might help
//using (CsvReader csvReader = new CsvReader(new StreamReader(filepath), true, '\t', '~', '`', '~', ValueTrimmingOptions.None))
int fieldcount = csvReader.FieldCount;
//Does not work, since it's read only property
//csvReader.Delimiter = "\t";
string[] headers = csvReader.GetFieldHeaders();
while (csvReader.ReadNextRecord())
for (int i = 0; i < fieldcount; i++)
string msg = String.Format("0\r1;", headers[i],
csvReader[i]);
Console.Write(msg);
Console.WriteLine();
【讨论】:
【参考方案4】:使用 OleDbConnection http://social.msdn.microsoft.com/Forums/en/winformsdatacontrols/thread/98fce7d7-b02d-4027-ad2e-2df3a28bd439
【讨论】:
【参考方案5】:也许你可以用你的应用程序打开文件,用另一个字符替换每个引号,然后处理它。
【讨论】:
【参考方案6】:我做了一些搜索,有一个 CSV 文件的 RFC (RFC 4180),这确实明确禁止他们在做什么:
每个字段可以用双引号括起来也可以不括起来(但是 某些程序(例如 Microsoft Excel)不使用双引号 完全)。如果字段没有用双引号括起来,那么 双引号不能出现在字段内。
基本上,如果他们想这样做,他们需要将整个字段括在引号中,如下所示:
,""SUMISEI MARU NO 2" - sea of Japan",
因此,如果您愿意,可以将这个问题抛给他们,并坚持让他们向您发送“正确”的 RFC 4180 CSV 文件。
由于您可以访问该 CSV 阅读器的源文件,另一种选择是修改它以处理它们提供给您的带引号的字符串。
这种情况正是让源代码访问您的工具集至关重要的原因。
如果您想在将文件提供给您的工具之前对其文件进行预处理(破解),正确的方法是查找带有引号的字段,而不是紧接在分隔符之前或之后的字段,并将其包含在整个字段中在另一组引号中。
【讨论】:
【参考方案7】:是的 - 经过一个深夜的红牛和挠头后,我最终发现了问题,它是“Claim_Description”字段中的逗号。甚至没有考虑过这一点,因为我使用的是制表符分隔的文件,但是一旦我对文件中的所有逗号进行了查找和替换,它就工作得很好!
下一步是在处理之前找出如何替换这些逗号。
再次感谢您的所有建议。
干杯,肖恩
【讨论】:
以上是关于制表符分隔文件中的引号的主要内容,如果未能解决你的问题,请参考以下文章