提取多个substr和匹配&用perl替换

时间:2012-12-20 18:45:50

标签: perl substr

我需要从一行中的固定位置提取多个子串,同时在另一个位置替换空格。

例如,我有一个字符串'01234567890'。我想在1,2,6,7,8位置提取字符,如果位置12,13是空格,我想用0101替换它们。这是基于位置的。

使用perl实现此目的的最佳方法是什么?

我可以使用substr和string比较然后将它们连接在一起,但代码看起来相当chuncky ....

2 个答案:

答案 0 :(得分:0)

我可能会将字符串拆分(或:爆炸)为单个字符数组:

my @chars = split //, $string; # // is special with split

现在我们可以做数组切片:一次提取多个参数。

use List::MoreUtils qw(all);

if (all {/\s/} @chars[12, 13]) {
   @chars[12, 13] = (0, 1);
   my @extracted_chars = @chars[1, 2, 6..8];
   # do something with extracted data.
}

然后我们可以将@chars变回像

这样的字符串
$string = join "", @chars;

如果你想删除某些字符而不是提取它们,你必须在循环中使用slice,这是一项丑陋的事业。

完成sub,界面漂亮,可以做这种事

sub extract (%) {
   my ($at, $ws, $ref) = @{{@_}}{qw(at if_whitespace from)};
   $ws //= [];
   my @chars = split //, $$ref;
   if (all {/\s/} @chars[@$ws]) {
      @chars[@$ws] = (0, 1) x int(@$ws / 2 + 1);
      $$ref = join "", @chars;
      return @chars[@$at];
   }
   return +();
}

my $string = "0123456789ab \tef";
my @extracted = extract from => \$string, at => [1,2,6..8], if_whitespace => [12, 13];

say "@extracted";
say $string;

输出:

1 2 6 7 8
0123456789ab01ef

答案 1 :(得分:0)

这是两个单独的操作,应该这样编码。这段代码似乎可以满足您的需求。

use strict;
use warnings;

my $str = 'abcdefghijab  efghij';

my @extracted = map { substr $str, $_, 1 } 1, 2, 6, 7, 8;
print "@extracted\n";

for (substr $str, 12, 2) {
  $_ = '01' if $_ eq '  ';
}
print $str, "\n";

<强>输出

b c g h i
abcdefghijab01efghij