行から固定位置にある複数のサブストリングを抽出すると同時に、別の位置にある空白を置き換える必要があります。
たとえば、文字列「01234567890」があります。位置1、2、6、7、8の文字を抽出すると同時に、位置12、13が空白の場合は、それらを0101に置き換えます。これはすべて位置ベースです。
perlを使用してこれを達成するための最良の方法は何ですか?
substrと文字列の比較を使用して、それらを連結することはできますが、コードはかなりぎこちなく見えました。
これは2つの別個の操作であり、そのようにコーディングする必要があります。このコードはあなたが必要とすることをしているようです。
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
私はおそらく文字列を単一の文字の配列に分割(または:分解)します:
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