【问题标题】:Use Regex to modify specific column in a CSV使用正则表达式修改 CSV 中的特定列
【发布时间】:2012-03-28 07:19:07
【问题描述】:

我希望将 CSV 中的一些 0000-2400 小时格式的字符串转换为 00-24 小时格式。例如

2011-01-01,"AA",12478,31703,12892,32575,"0906",-4.00,"1209",-26.00,2475.00
2011-01-02,"AA",12478,31703,12892,32575,"0908",-2.00,"1236",1.00,2475.00
2011-01-03,"AA",12478,31703,12892,32575,"0907",-3.00,"1239",4.00,2475.00

第 7 列和第 9 列分别是出发和到达时间。当我完成后,这些线条最好看起来像这样:

2011-01-01,"AA",12478,31703,12892,32575,"09",-4.00,"12",-26.00,2475.00

整个 csv 最终将被导入到 R 中,我想尝试预先处理一些处理,因为它会有点大。我最初尝试使用 Perl 来执行此操作,但我无法使用正则表达式选择多个数字。我可以使用后向表达式在给定逗号前获得一个数字,但不能超过一个。

我也愿意被告知在 Perl 中这样做是不必要的愚蠢,我应该坚持使用 R。:)

【问题讨论】:

  • 我会考虑使用专门用于处理 csv 的模块,例如 Text::CSV

标签: regex perl r csv


【解决方案1】:

我不妨提供我自己的解决方案,即

s/"(\d\d)\d\d"/"$1"/g

【讨论】:

    【解决方案2】:

    就像我在 cmets 中提到的那样,使用像 Text::CSV 这样的 CSV 模块是一个安全的选择。这是一个如何使用它的快速示例脚本。您会注意到它不保留引号,但它应该保留引号,因为我输入了keep_meta_info。如果它对你很重要,我相信有办法解决它。

    use strict;
    use warnings;
    use Data::Dumper;
    
    use Text::CSV;
    my $csv = Text::CSV->new({
            binary => 1,
            eol => $/,
            keep_meta_info => 1,
    });
    while (my $row = $csv->getline(*DATA)) {
        for ($row->[6], $row->[8]) {
            s/\d\d\K\d\d//;
        }
        $csv->print(*STDOUT, $row);
    }
    
    __DATA__
    2011-01-01,"AA",12478,31703,12892,32575,"0906",-4.00,"1209",-26.00,2475.00
    2011-01-02,"AA",12478,31703,12892,32575,"0908",-2.00,"1236",1.00,2475.00
    2011-01-03,"AA",12478,31703,12892,32575,"0907",-3.00,"1239",4.00,2475.00
    

    输出:

    2011-01-01,AA,12478,31703,12892,32575,09,-4.00,12,-26.00,2475.00
    2011-01-02,AA,12478,31703,12892,32575,09,-2.00,12,1.00,2475.00
    2011-01-03,AA,12478,31703,12892,32575,09,-3.00,12,4.00,2475.00
    

    【讨论】:

    • 感谢此次更新。我最初只是需要一些愚蠢和不安全的东西,但这可能更明智。 :)
    猜你喜欢
    • 1970-01-01
    • 2020-05-10
    • 2013-02-07
    • 1970-01-01
    • 2014-04-14
    • 1970-01-01
    相关资源
    最近更新 更多