【问题标题】:Regex to keep only first N columns in every line of CSV file正则表达式在 CSV 文件的每一行中只保留前 N 列
【发布时间】:2013-07-19 03:53:06
【问题描述】:

我正在使用 Perl 处理 CSV 文件。

如何在从第五个逗号开始的每一行中删除所有内容(换行符除外)?

例如"a,b,c,d,e,f,g,h,i,\n" 将变为 "a,b,c,d,e\n"

$entire_csv_file_contents =~ s/what do I write here?//gm;

因为数据不会包含引用字段等,所以这里不必使用Text::CSV

【问题讨论】:

    标签: regex perl multiline regex-negation


    【解决方案1】:

    例如:

    $entire_this_is_not_csv_file_contents =~ s/^(([^,]+,){4}[^,]+).*/$1/gm;
    

    如果您不需要 perl 5.8.x 兼容性,您可以使用 \K 转义,因此不需要捕获(感谢 amon 的建议):

    $entire_this_is_not_csv_file_contents =~ s/^(?:[^,]+,){4}[^,]+\K.*//gm;
    

    另外,根据字段是否为空,您应该将此处的“+”替换为“*”(也感谢 amon)。

    【讨论】:

    • …也称为s/^(?:[^,]*,){4}[^,]*\K.*//gm;我非常喜欢避免不必要的捕获。 (另外,* 量词允许空字段)。
    • @amon,这可能不是一个单独的答案吗?
    • 感谢您提供有关兼容性的补充信息。
    【解决方案2】:

    您不一定需要正则表达式:

    use strict;
    use warnings;
    
    chomp(my $line = "a,b,c,d,e,f,g,h,i,\n");
    my $cutoff = 5;
    my $shortened_line = join(',', (split(/,/, $line, $cutoff+1))[0..$cutoff-1]);
    
    print "$shortened_line\n";   # => a,b,c,d,e
    

    【讨论】:

    • /,/ 也不是正则表达式吗?
    • s/regex/substitution operator/;
    【解决方案3】:

    不要使用正则表达式。您将不得不处理包含逗号或转义引号的引用字段的可能性。

    改为使用 Perl 模块 Text::CSV 将输入行正确解析为字段,然后仅输出您感兴趣的字段。

    【讨论】:

    • 在这种情况下,引用字段是不可能的。假装我没有说 CSV? :)
    • Kev:你为什么这么讨厌使用那个模块?它有一个很好的界面,你不必重新发明,经验告诉我,你现在必须解析的如此简单的格式很快就会变成一场全面的噩梦。您可能会听到的下一个问题是“如何添加颜色?”。
    • @innaM,有时我更喜欢模块,但有时我更喜欢较少的依赖项(如果你想将其解释为“非常讨厌那个模块”,那么......继续吧。:))我想要知道也是因为我对一般技术很好奇。如果是 HTML 或其他内容,我可能会接受“你问错问题”的答案,但在这种情况下,我有充分的理由不相信这会变成“全面的噩梦”。我不确定谁会提出颜色问题,但我可以保证,不会是我......我只是想要一个正则表达式来学习:)
    【解决方案4】:

    这不是 perl,但也许有帮助:

    cut -d, -f1-5 test.csv
    

    【讨论】:

    • 它是 win32 上更大的 perl 脚本的一部分。我没有可用的cut
    猜你喜欢
    • 2016-11-14
    • 1970-01-01
    • 1970-01-01
    • 2013-11-29
    • 1970-01-01
    • 1970-01-01
    • 2014-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多