在混合整数字符串数据中拆分和计算子字符串

时间:2016-01-27 12:30:06

标签: perl split

输入数据(示例):

40A3B35A3C
30A5B28A2C2B

所需输出(每行)是由代码40A3B35A3C的组成和以下规则确定的单个数字:

if A - add the proceeding number to the running total
if B - add the proceeding number to the running total
if C - subtract the proceeding number from the running total

40A 3B 35A 3C因此会产生40 + 3 + 35 - 3 = 75。

两行的输出:

75
63

是否有一种有效的方法可以使用单行程序在制表符分隔的.txt文件中为特定列(例如$F[2])实现此目的?我考虑将整个代码分成单个字符,然后执行if语句检查以检测A / B / C,但我的Perl知识有限,我不确定如何解决这个问题。

4 个答案:

答案 0 :(得分:3)

当您使用split捕获时,捕获的组也会从拆分返回。

perl -lane '
    @ar = split /([ABC])/, $F[2];
    $s = 0;
    $s += $n * ("C" eq $op ? -1 : 1) while ($n, $op) = splice @ar, 0, 2;
    print $s
' < input

或许更具说明性:

BEGIN { %one = ( A =>  1,
                 B =>  1,
                 C => -1 ) }
@ar = split /([ABC])/, $F[2];
$s = 0;
$s += $n * $one{$op} while ($n, $op) = splice @ar, 0, 2;
print $s

答案 1 :(得分:1)

当处理像这样的字符串时,知道正则表达式可以返回结果列表是有用的。

E.g。

my @matches = $str =~ m/(\d+[A-C])/g; #will catch repeated instances

所以你可以这样做:

#!/usr/bin/env perl
use strict;
use warnings;

while (<DATA>) {
    my $total;
    #break the string into digit+letter groups.
    for (m/(\d+[A-C])/g) {
        #separate out this group into num and code. 
        my ( $num, $code ) =  m/(\d+)([A-C])/;
        print "\t",$num, " => ", $code, "\n";
        if ( $code eq "C" ) {
            $total -= $num;
        }
        else {
            $total += $num;
        }
    }
    print $total, " => ", $_;
}

__DATA__
40A3B35A3C
30A5B28A2C2B

答案 2 :(得分:1)

perl -lne 'push @a,/([\d]+)[AB]/g;
           push @b,/([\d]+)[C]/g;
           $sum+=$_ for(@a);$sum-=$_ for(@b);
           print $sum;@a=@b=();undef $sum' Your_file

答案 3 :(得分:1)

如何运作

  • 使用命令行arg作为输入
  • 将哈希值“%op”设置为 每个字母的操作
  • 将字母替换为
  • 中的运算符
  • 输入将替换输入评估为表达式
use strict;
use warnings;

my %op=qw(A + B + C -);
$ARGV[0] =~ s/(\d+)(A|B|C)/$op{$2} $1/g;
print eval($ARGV[0]);