Perl根据模式从字符串矩阵中删除字符

时间:2015-01-14 10:57:10

标签: regex string perl matrix

我在哈希数据结构中存储了多个具有相同长度的字符串。 示例:

$VAR1 = {
          'first' => 'abcXY',
          'second' => 'XYXYa',
          'third' => '*abXZ'
        };

从这个'矩阵'对于字符,我想删除'列'它只包含字符XY。在上面的例子中,这将是每个字符串的第四个字符(第4个'列')。 期望的结果是:

$VAR1 = {
          'first' => 'abcY',
          'second' => 'XYXa',
          'third' => '*abZ'
        };

以下代码通过创建哈希结构值的转置,然后确定要保留哪些索引来实现此目的:

# data structure
my %h = ('first'=>'abcXY', 'second'=>'XYXYa', 'third'=>'*abXZ' );

# get length of all values in hash
my $nchar = length $h{(keys(%h))[0]};

# transpose values of hash
my @transposed = map { my $idx=$_; [map {substr ($_, $idx, 1) } values(%h)]  } 0..$nchar-1; 

# determine indices which I want to keep
my @indices;
for my $i (0..$#transposed){
        my @a = @{$transposed[$i]};

        # do not keep index if column consists of X and Y
        if ( scalar(grep {/X|Y/} @a) < scalar(@a) ) {
                push @indices, $i;
        }   
}

# only keep letters with indices
for my $k (keys %h){
        my $str = $h{$k};
        my $reduced = join "", map{ substr ($str, $_, 1) } @indices;
        $h{$k} = $reduced;
}

这是一个非常简单的操作代码。我怎么能更优雅地做到这一点(最好不要使用一些矩阵库,但使用标准的perl)?

修改

这是另一个示例:从以下字符串开始,应删除第一个和最后一个字符,因为在两个字符串中,第一个和最后一个位置是XY

$VAR1 = {
          '1' => 'Xsome_strX',
          '2' => 'YsomeXstrY'
        };

期望的结果:

$VAR1 = {
          '1' => 'some_str',
          '2' => 'someXstr'
        };

1 个答案:

答案 0 :(得分:1)

my $total = values %hash;
my %ind;
for my $v (values %hash) {

  $ind{ pos($v) -1 }++ while $v =~ /[XY]/g;
}
my @to_remove = sort {$b <=> $a} grep { $ind{$_} == $total } keys %ind;

for my $v (values %hash) {

  substr($v, $_, 1, "") for @to_remove;
}