0

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

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

使用 perl 实现这一目标的最佳方法是什么?

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

4

2 回答 2

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在循环中使用 s ,这是一个丑陋的任务。

用漂亮的界面完成子来做这种事情

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
于 2012-12-20T19:22:57.633 回答
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
于 2012-12-21T01:54:58.313 回答