我已经定义了follwing秒差距解析器解析CSV文件转换成字符串的表,即[[String]]
秒差距CSV解析器解析额外的行
--A csv parser is some rows seperated, and possibly ended, by a newline charater
csvParser = sepEndBy row (char '\n')
--A row is some cells seperated by a comma character
row = sepBy cell (char ',')
--A cell is either a quoted cell, or a normal cell
cell = qcell <|> ncell
--A normal cell is a series of charaters which are neither , or newline. It might also be an escape character
ncell = many (escChar <|> noneOf ",\n")
--A quoted cell is a " followd by some characters which either are escape charaters or normal characters except for "
qcell = do
char '"'
res <- many (escChar <|> noneOf "\"")
char '"'
return res
--An escape character is anything followed by a \. The \ will be discarded.
escChar = char '\\' >> anyChar
我真的不知道,如果意见是太多了,烦人,如果他们在帮助。作为Parsec noob他们会帮助我,所以我想我会添加它们。
它工作的很好,但有一个问题。它会在表格中创建一个额外的空行。因此,例如,如果我有一个包含10行的csv文件(即只有10行,最后没有空行 *),[[String]]
结构的长度将为11,而最后一列String
将包含1个元素。一个空的String
(至少这是使用show
打印时的显示方式)。
我的主要问题是:为什么这个额外的行出现,我能做些什么来阻止它?
我注意到的另一件事是,如果在csv文件中的数据之后有空行,这些行将最终为表中只包含空的String
的行。我认为使用sepEndBy
而不是sepBy
会使多余的空行被忽略。这不是这种情况吗?
*看着十六进制编辑器的文本文件后,它似乎的确实际上换行符结束,尽管VIM不显示它...
对不起。我没有说我的问题完全正确。事实证明,额外的行和空行行实际上在解析时不会变为空列表。相反,它们最终包含1个看起来是空的“String”的元素。我会改变我的问题反映这一点。 您的解决方案在任何情况下都无效。可能是因为我没有正确说明问题。但我应该使用'sepBy1',所以谢谢你的帮助:) – 2012-07-23 20:37:26
@andvin问题是'many'和'sepBy'可以不消耗,而终止'sep'是'sepEndBy'的可选项。当达到最后的'\ n''时,解析器尝试用剩余的输入读取另一行。 'row'试图解析第一个单元格。 'ncell'用'“”成功,行查找'',','找不到,用一个单元'[“”]'成功。 'rows'检查一个''\ n',发现没有,并且最后一行成功['“]]。如果在'ncell'中使用'many1',但在行中不使用'sepBy1',则必须在emty输入中同时使'cell'和'row'失效,以摆脱最后一个空行('[]')。 – 2012-07-23 21:04:51
谢谢!这解决了这个问题。但是现在我不能有空单元,但是我可以看到如何区分只有一个空单元的空行和行是不可能的。但也许可以用一个空单元区分行,而最后一个不存在的行是可能的?也许如果我用'sepBy'而不是'sepEndBy'?我的意思是,应该可以区分空行和EOF之间的区别吗? 无论如何,我想我应该看看csv是如何定义的,以及它是否允许不同长度的行。 – 2012-07-24 21:08:45