我已经得到了一个包含7列的CSV文件,直到最近我还做得很好,他们开始在第三列数据内使用逗号,还在第三列内使用CR和LF字符,所有这些都在双引号之间。

我正在逐行阅读它,因此可以与另一个文件进行交叉检查,并将其指向另一个文件中的右行,但是现在它们包括新的行代码和逗号,我的代码只是搞砸了。

例如:


1,4778,"El murciélago estaba navegando",10/08/2010,906610,13496-86219-1,1。这个运行得很好。
1,4778,"El murciélago estaba navegando,
y además estaba de parranda",10/08/2010,906610,13496-86219-1,1
。现在,这很糟糕。


您有什么建议解决这个问题的方法吗?第三数据列始终是发生这些突然变化的列。其他人将永远无法使用新行或其他逗号,因此无需过滤这些行。

提前致谢!

最佳答案

处理它的最干净,最系统的方法可能是逐字符读取字符并使用小型状态机,以处理诸如“我们位于带引号的字符串内,因此忽略任何逗号,CR或LF”之类的问题。

一种方法是建立一个数组,其中每一行都是当前状态,每一列都是可能的输入字符。您读取了一个输入字符,并根据当前状态和输入字符,获得了下一个输入状态。通常,您还会有一个case语句,以根据当前状态和下一个状态执行操作(例如,当允许将所读取的内容作为字段的一部分时,将当前字符附加到您的CurrentField字符串中),或者到达字段结尾时,保存当前的字段字符串。

因此,您从“开始”状态开始。在“开始”状态下,如果看到报价,则转到“ QuotedField”状态。如果看到字母或数字,则进入UnQuotedField状态。如果看到逗号,则进入EndField状态(即,您仅读取一个空字段)。如果您看到许多其他内容,则进入“错误”状态。

在QuotedField状态中,除引号外的任何内容都将被接受,并使您处于QuotedField状态。当您看到引号时,您需要检查下一个字符是引号(双引号转换为嵌入在字段中的引号)还是其他内容(表示引号标记了字段的结尾)。您可以通过手工编写一些代码来窥视下一个输入字符,并检查其是否为引号,或者可以对另一个状态进行编码,如果它获得了引号,则可以返回到QuotedField状态,即EndField状态如果发现逗号或几乎其他所有内容(例如字母或数字)的错误状态。

关于delphi - 用Delphi处理CSV文件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3472285/

10-13 02:43