【问题标题】:Changing CSV file with regexes使用正则表达式更改 CSV 文件
【发布时间】:2015-04-26 07:05:19
【问题描述】:

因为同时我给question, what got closed写了一个答案 - 试图改写并重新询问它。

拥有一个包含 1.8 亿条记录的 CSV 文件,其中 5 列为:

"c a","L G-3 (8) N (4th G P Q C- 4 R- 1 T H- 15.6 I- W 8.1) (B)","C & P_L",1,0

如何将其更改为 3 列结构为:

"c a|L G-3 (8) N (4th G P Q C- 4 R- 1 T H- 15.6 I- W 8.1) (B)|C & P_L",1,0

例如需要将列 1,2,3 与 | 连接起来并将其打印为一列,其他列保持不变

用正则表达式尝试过:

cat RelatedKW.csv | perl -pe 's/(\|)/\//g'| perl -pe 's/("\s*"|"\s*"\s*\\n$)//g'| perl -pe 's/^,"|,,|"\s*,\s*\"/|/g' | perl -pe 's/\"(\d+),(\d+)\"/ |$1|$2/g' > newRKW4.csv`

这里有更好的方法吗?

【问题讨论】:

  • 不要重复提问。编辑您之前的问题。

标签: regex perl


【解决方案1】:

您通常应避免使用正则表达式解析 CSV,正如 Kent Fredric 在回答 another similar question 时所解释的那样:

不使用 CPAN 真的是灾难的根源。

请在尝试编写自己的 CSV 实现之前考虑这一点。 Text::CSV 有超过一百行代码,包括修复的错误和边缘情况, 从头开始重新编写只会让您了解 CSV 是多么糟糕。

尝试使用正则表达式解析 CSV 是真的不好的做法,因为例如,您需要处理:

  • 转义引号
  • 转义的分隔符
  • 包含分隔符的字段

等等,Text::CSV 将为您处理所有这些。

这是一个使用 Text::CSV 的解决方案。我不是 Perl 专家,所以下面的代码可能会遗漏一些东西,但它可能比使用正则表达式更好:

perl -MText::CSV_XS -E '$csv = Text::CSV_XS->new ({ eol => $/ }); $csv->print(*STDOUT, [join(q{|}, @$row[0..2]), @$row[3..4]]) while ($row = $csv->getline(*STDIN))' < csv

输入:

"c a","L G-3 (8) N (4th G P Q C- 4 R- 1 T H- 15.6 I- W 8.1) (B)","C & P_L",1,0

输出:

"c a|L G-3 (8) N (4th G P Q C- 4 R- 1 T H- 15.6 I- W 8.1) (B)|C & P_L",1,0

一些潜在的问题:它不处理 | 字符的转义,如果输入中有任何字符,没有错误处理等。为了更好的解决方案,您需要编写一个功能齐全的 Perl 脚本而不是单线。

【讨论】:

  • 您可能会感到惊讶,但正则表达式并不总是适合这项工作的工具,而且 CSV 解析与普遍的看法相反并非微不足道。所以有很多选择,要么重新发明你自己的(坏了?)轮子,要么使用正确的工具来完成这项工作。
  • 我了解您正试图直接回复已关闭的问题的 OP,但“对话”(例如“另一方面,我理解您。您可能不是程序员。”)在这里没有任何意义。我已将其清理干净,因此您的回答实际上对其他用户有意义。我认为您应该编辑原始问题,而不是发布重复的问题,这样它不会太宽泛,然后如果人们认为该问题对网站有价值,他们可以投票重新打开。
  • @ThisSuitIsBlackNot 是的。我明白 - 你是对的 - 谢谢你的编辑。 (对不起,我只是被一些 cmet 弄得有点不高兴,需要冷静下来)。编辑原始问题并投票支持重新开放肯定是最好的方法。
  • 感谢您在此主题上所做的努力以及您建议 Text::CSV +1
  • @Сухой27 我不会感到惊讶 - 正如你所看到的,我正在使用 Text::CSV - 所以,我不明白你的评论 - 重新发明了什么 i> 在我的(正如你所说 - 我的坏了?)解决方案中?你能说得更具体点吗?
【解决方案2】:

假设您的数据与它应该工作的完全一样

$line =~ s-\",\"-|-g;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-02
    • 2011-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多