【问题标题】:Replace improper commas in CSV file替换 CSV 文件中不正确的逗号
【发布时间】:2015-06-23 09:37:07
【问题描述】:

这个问题以前可能有人问过,但我找不到。我有一个 CSV 文件列表(大约 439 个),其中一些文件中,有人还在编辑 cmets 中使用了逗号。结果是我无法将文件放入数据框中,因为文件在拆分后现在没有相同数量的元素。无论如何,我面临的问题是这样的:

vec1 <- paste("484,1213,0,62.0006,1,go -- late F1 max, but glide?")
vec2 <- paste("467,1387,0,62.0026,1,goes2")

ls <- list(vec1, vec2)

我想要做的是有一个六列的数据框。如果 vec1 的编辑 cmets 中没有逗号,我可以使用(并且一直在使用,直到我发现这个有问题的示例)以下内容:

df <- ldply(ls, function(x)unlist(strsplit(x[1], split = ",")))

但是,我收到了明显的错误消息,即结果的长度数不同。有没有办法摆脱那个逗号,或者把它变成一个分号,或者确保,如果一个向量中有 7 个元素,那么 6 和 7 是结合在一起的?

如果有帮助,这就是我在 R 中读取文件的方式(我正在使用 scan,因为文件中还有我想要的其他信息。这里也有一些奇怪的编码问题,但是这似乎有效)。

data <- scan(file, fileEncoding="latin1", blank.lines.skip = FALSE, what = "list", sep = "\n", quiet = TRUE)   

【问题讨论】:

  • 如果不需要的逗号总是在最后一个元素中并且你之前有“--”,你可以把“--”作为scan调用中的注释字符,这样它就会被忽略?
  • 嗨,谢谢。我认为这可能奏效了。顺便说一句,是否可以将“--”作为评论字符(我收到一条错误消息,但单个(“-”似乎可以工作)。
  • 如果您需要 cmets,您仍然可以将第 6 个逗号替换为分号并使用您之前的解决方案:gsub("((?:[^,]*,){5}[^,]*),", "\\1;", vec1, perl=TRUE)。但是,它不会“规范化”后面可能出现的任何其他逗号。
  • @JoeF,不知道,我认为“--”实际上会起作用,不明白为什么它不起作用......但从来没有使用超过一个字符
  • @stribizhev 或sub("^([^,]+,){5}[^,]+\\K,", ";", vec1, perl=T)

标签: regex r csv


【解决方案1】:

如果您需要 cmets,您仍然可以将第 6 个逗号替换为分号并使用您之前的解决方案:

gsub("((?:[^,]*,){5}[^,]*),", "\\1;", vec1, perl=TRUE)

正则表达式解释

  • ((?:[^,]*,){5}[^,]*) - 一个捕获组,我们将其称为组 1,替换模式中带有 \\1,匹配
    • (?:[^,]*,){5} - 5 个非逗号字符序列,后跟一个逗号
    • [^,]* - 0 个或多个非逗号
  • , - 我们将在替换中将逗号变成;

或者(正如@CathG 指出的那样,\\K 运算符也可以与类似 Perl 的表达式一起使用)

sub("^([^,]+,){5}[^,]+\\K,", ";", vec1, perl=T)

来自PCRE documentation

转义序列\K 导致任何先前匹配的字符不包含在最终匹配的序列中。

但是,它不会“规范化”后面可能出现的任何其他逗号。

【讨论】:

  • 既然它有帮助,我将发布答案。实际上,我认为在这里使用 \K 没有任何意义,因为只是反向引用会产生类似的结果。
猜你喜欢
  • 2011-02-26
  • 2014-12-06
  • 2011-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多