【问题标题】:R .csv not read in correctly because there are double quotes in the textR .csv 无法正确读取,因为文本中有双引号
【发布时间】:2019-06-03 10:18:12
【问题描述】:

我有一个包含所有文本字段的 .csv 文件。但是,某些文本字段包含未转义的双引号字符,例如:

"ID","Text","Optional text","Date" 
"1","Today is going to be a good day","","2013-02-03"
"2","And I am inspired by the quote "every dog must have it's day"","Hi","2013-01-01"
"3","Did not the bard say All the World's a stage" this quote is so true","Terrible","2013-05-05"

第 1 行和第 2 行很好,但第 3 行没有正确读入。目前,我正在手动浏览 Notepad++ 中的文件以尝试删除此类引号。理想情况下,我希望 R 能够处理这个问题,但我认为无与伦比的双引号的未转义性质使得这种期望不合理。

在 Notepad++ 中,我正在尝试构建一个正则表达式来识别没有逗号之前或之后的双引号。逻辑是有效的双引号将位于字段的开头或结尾,这由相邻的逗号表示。这可能有助于确定我的大部分案件,然后我可以处理这些案件。

只是说我有大约 340 万条记录,大约 0.1% 似乎有问题。

编辑: 已建议使用来自 data.table 的 fread 作为替代方案,但使用 fread 更不成功:

1: In fread(paste(infilename, "1", ".csv", sep = "")) :
  Stopped early on line 21. Expected 18 fields but found 9. Consider fill=TRUE and comment.char=. First discarded non-empty line

建议的选项均无效。我认为这是因为“文本”字段也可以包含 CRLF 字符。 read.csv 似乎只是忽略了这些(好),而 fread 例外。抱歉,我无法提供实际文本,但这里有一些更全面的测试数据,其中包含不匹配的双引号(read.csv 有问题)和 CRLF(fread 有问题)。

"ID","Text","Optional text","Date" 
"1","Today is going to be a good day","","2013-02-03"
"2","And I am inspired by the quote "every dog must have it's day"","Hi","2013-01-01"
"3","An issue with this line is that it contains a CRLF here 
which is not usual.","Again an unusual CRLF
is present in these data","2013-02-02"
"4","Did not the bard say All the World's a stage" this quote is so true","Terrible","2013-05-05"

帮助使用 Notepad++ 中的正则表达式会很棒。

【问题讨论】:

  • 您能否通过 1) 共享(部分)数据的输入来使您的示例具有可重复性和更好的理解性? 2)告诉我们你用什么函数来读取数据,3)告诉我们这个问题是什么?
  • 这个可以和 np++ 一起工作吗?搜索 (?:^\h*"|","|"\h*$)(*SKIP)(*F)|" 并替换为 \\"
  • 我无法将有问题的数据读入 R,所以我不能 dput() 任何东西?
  • np++ 将 (?:^\h*"|","|"\h*$)(*SKIP)(*F)|" 报告为无效的正则表达式。
  • 你能保证所有引用的文字都不包含逗号吗?然后,您可以简单地使用 quote = "" 导入并删除每个字符串开头和结尾的双引号作为后处理步骤。我希望你拜访收集数据的人,并就你的问题对他们进行教育。

标签: r regex notepad++


【解决方案1】:

也许一种选择是在 notepad++ 中使用条件替换。

您可以找到所有以双引号开头、以逗号开头或在字符串开头的字符串。

然后不匹配双引号,直到遇到下一个逗号后跟或字符串结尾的双引号。这些是白色的线是可以的,所以对于你想要捕获和替换的替换部分,匹配一个不在逗号之间的双引号。

查找内容:

(?:^|,)"[^"\n]*"(?=$|,)|(?<!,)(")(?!,)

替换为:

有条件的替换。如果是第 1 组,则替换为空,否则替换为匹配项。

(?{1}:$0)

Regex demo

说明

  • (?:^|,) 匹配逗号或断言字符串的开头
  • "[^"\n]*" 中间没有双引号时匹配双引号
  • (?=$|,)断言右边是字符串的结尾或逗号
  • |
  • (?&lt;!,)(")(?!,)在 group1 中捕获双引号,同时断言左侧和右侧的内容不是逗号

【讨论】:

  • 我想要的是找到一个左侧或右侧没有逗号的双引号。即在asdf asdf" asdf" jjkn k 中找到双引号,但在," 此处找不到双引号,在此处", 或在此处,"", 找不到。
  • 网络工具看起来不错。如何更改正则表达式,使其不在行首和行尾拾取双引号?谢谢 。 regex101.com/r/QdFJwm/3
  • @StephenClark 你可以使用(?&lt;!^)(?&lt;!,)["“](?!(?:,| *$)) demo
【解决方案2】:

似乎与data.table::fread 配合得很好:

fread("E:/temp/test.txt")
#   ID                                                                 Text Optional text     "Date"
#1:  1                                      Today is going to be a good day               2013-02-03
#2:  2        And I am inspired by the quote "every dog must have it's day"            Hi 2013-01-01
#3:  3 Did not the bard say "All the World's a stage" this quote is so true      Terrible 2013-05-05
#Warning message:
#In fread("E:/temp/test.txt") :
#  Found and resolved improper quoting in first 100 rows. If the fields are not quoted (e.g. field separator does not appear within any field), try quote="" to avoid this warning.

【讨论】:

  • 谢谢。我尝试使用 fread,但文件存在其他问题,这意味着 fread 更不成功(我会将这些添加到上面的原始帖子中)。目前我最好的选择是使用 {read.csv} 但尝试清理一些双引号问题。
猜你喜欢
  • 2019-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-15
  • 2020-03-11
  • 2019-02-15
  • 2014-12-23
  • 1970-01-01
相关资源
最近更新 更多