【问题标题】:CSV file - how to limit fields length using regexp in PerlCSV 文件 - 如何在 Perl 中使用正则表达式限制字段长度
【发布时间】:2015-08-04 09:28:56
【问题描述】:

我正在解析一个分号分隔的 CSV 文件,其中行如下所示

firstField;secondField;thirdField;fourth very long field which I need to truncate;fifth very long field which I need to truncate"

我需要将所有字段截断为 10 个字符

我可以像在

中那样逐个字段地截断它
open my $input, "<", "inputFile.txt" or die "Can't open the inputFile.txt";
while (my $line = <$input>){
     chomp($line);
     my @fields = split(';',$line);
     for $field (@fields){
         $field =~ s/.{10}\K.*// if ((defined $field) && (length $field > 10));
         }
     }

有没有什么方法可以有一个正则表达式,可以在行级别上实现这一点? 像

$line = s/;.{10}\K.*;?//g

【问题讨论】:

    标签: regex perl csv text-parsing


    【解决方案1】:

    我认为你可以使用这样的正则表达式:

    /(^|;)(([^;]{1,10})([^;]*))/g
    

    替换为$3

    [Regex Demo]

    【讨论】:

    • 所以代码看起来像 $line =~ s/(^|;)(([^;]{1,10})([^;]*))/$3/gm ; ?
    【解决方案2】:

    是否需要作为正则表达式完成?我想我会在你的split 行中放一张地图并使用substr

    my @fields = 
      map { length > 10 ? substr($_, 0, 10) : $_ }
      split(/;/,$line);
    

    这对我来说更易于维护。

    【讨论】:

    • 实际上它确实需要是一个正则表达式,因为我不想遍历数组,我认为显然是哪个映射。
    【解决方案3】:

    它不应该那么复杂。使用 Perl 的功能和
    只删除超过 10 个字符的内容。不需要像 {1,10} 这样的范围。

    插入整个文件,对整个文件进行替换。
    让生活更轻松。

    $csv_str =~ s/(?m)(?:^|;)[^;\n]{10}\K[^;\n]+//g;

     (?m)           # Multi-line mode
     (?: ^ | ; )    # BOL (beginning of line) or semi-colon
     [^;\n]{10}     # 10 chars, not semi-colon nor linebreak
     \K             # Clear the match buffer of all previous data
     [^;\n]+        # This is to be gotten rid of...
                    # 1 or more not semi-colon nor linebreak
                    # On to the next match
    

    匹配:

     **  Grp 0 -  ( pos 21 , len 1 ) 
    d  
    
    -----------------------
    
     **  Grp 0 -  ( pos 44 , len 37 ) 
    y long field which I need to truncate  
    
    -----------------------
    
     **  Grp 0 -  ( pos 92 , len 37 ) 
     long field which I need to truncate"  
    

    【讨论】:

    • 我如何“啜饮”整个文件?
    • $/ = undef; my $csv_str = &lt;$fh&gt;; 或使用 slurp 包。
    • 不会影响我的记忆力吗?我正在解析的一些文件是 10M+。
    • 顺便说一句。之前忘了提,你的正则表达式是我正在寻找的东西。虽然我还没有完全理解:)
    • 10 兆字节意味着什么的日子已经一去不复返了。在正则表达式中添加了一些 cmets。
    猜你喜欢
    • 1970-01-01
    • 2021-06-15
    • 2012-07-18
    • 1970-01-01
    • 2017-01-09
    • 1970-01-01
    相关资源
    最近更新 更多