0

行から固定位置にある複数のサブストリングを抽出すると同時に、別の位置にある空白を置き換える必要があります。

たとえば、文字列「01234567890」があります。位置1、2、6、7、8の文字を抽出すると同時に、位置12、13が空白の場合は、それらを0101に置き換えます。これはすべて位置ベースです。

perlを使用してこれを達成するための最良の方法は何ですか?

substrと文字列の比較を使用して、それらを連結することはできますが、コードはかなりぎこちなく見えました。

4

2 に答える 2

0

これは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
于 2012-12-21T01:54:58.313 に答える
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 に答える