【问题标题】:Multi-order splitting inside PerlPerl 中的多阶拆分
【发布时间】:2019-10-23 06:10:11
【问题描述】:

我有一个来自 CSV 文件的字符串:

my $str = 'NA19900,4,111629038,0;0,0;0,"GSA-rs16997168,rs16997168,rs2w34r23424",C,T,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0';

应该(以某种方式)翻译成

'NA19900,4,111629038,0;0,0;0,"GSA-rs16997168;rs16997168;rs2w34r23424",C,T,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0';

这样 perl 的 split 不会将单个字段 GSA-rs16997168,rs16997168 拆分为两个单独的字段

即如果逗号在两个 " 之间,则逗号应替换为分号我在 Google 上找不到如何执行此操作

到目前为止我已经尝试过:

  1. $str =~ s/"([^"]+),([^"]+)"/"$1;$2"/g; 但这会因 > 2 个表达式而失败

  2. 1234563那:(
  3. 我听说过前瞻,但我不知道如何在这里使用它们:(

【问题讨论】:

    标签: regex perl csv


    【解决方案1】:

    既然存在完美的 CSV 解析器,为什么还要尝试重新创建?

    use Text::CSV_XS qw( );
    
    my $csv = Text::CSV_XS->new({ binary => 1, auto_diag => 2 });
    while ( my $row = $csv->get_line($fh) ) {
       $row->[5] =~ s/,/;/g
       $csv->say(\*STDOUT, $row);
    }
    

    【讨论】:

      【解决方案2】:

      我的猜测是,我们希望在最后一个 " 之后最多捕获四个逗号,为此我们将从一个简单的表达式开始,例如:

      (.*",.+?,.+?,.+?,.+?),
      

      Demo

      测试

      use strict;
      
      my $str = 'NA19900,4,111629038,0;0,0;0,"GSA-rs16997168,rs16997168,rs2w34r23424",C,T,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0';
      my $regex = qr/(.*",.+?,.+?,.+?,.+?),/mp;
      
      if ( $str =~ /$regex/g ) {
        print "Whole match is ${^MATCH} and its start/end positions can be obtained via \$-[0] and \$+[0]\n";
        # print "Capture Group 1 is $1 and its start/end positions can be obtained via \$-[1] and \$+[1]\n";
        # print "Capture Group 2 is $2 ... and so on\n";
      }
      
      # ${^POSTMATCH} and ${^PREMATCH} are also available with the use of '/p'
      # Named capture groups can be called via $+{name}
      

      正则表达式

      如果不需要此表达式并且您希望对其进行修改,请访问此链接regex101.com

      正则表达式电路

      jex.im 可视化正则表达式:

      【讨论】:

        【解决方案3】:

        为什么要使用 CSV 模块和正则表达式。
        只需使用正则表达式并去掉中间人。

        $str =~ s/(?m:(?:,|^)"|(?!^)\G)[^",]*\K,(?=[^"]*")/;/g ;

        https://regex101.com/r/tRDCen/1

        自述版本

         (?m:
              (?: , | ^ )
              "
           |  
              (?! ^ )
              \G 
         )
         [^",]* 
         \K 
         ,
         (?= [^"]* " )
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-11-07
          • 2019-07-28
          • 1970-01-01
          • 2012-07-30
          • 2011-11-12
          • 2014-06-21
          • 1970-01-01
          • 2014-04-06
          相关资源
          最近更新 更多