2

編集:tr ///は変数補間をサポートしていないので、s/\Q$_\E//g;代わりに

または、おそらく、私は何か正しいことをしていません...

私は次のコードを持っています:

#!/usr/bin/perl

use strict;
use warnings;
use utf8;

sub strip_invalid {
  my ($str, @chars) = @_;

  map { $str =~ tr/$_//; } @chars;

  return $str;
}

my @invalid = qw( a e i o u );

print strip_invalid("This is the super sample with vowels.\n", @invalid);

文字列をに渡して、文字を削除したいstrip_invalid()tr///です@invalidmap...どこが間違っていたのですか?(ちなみに、正規表現を使用すると機能します)。

4

3 に答える 3

7

Perlのtr機能は変数をサポートしていません

変換テーブルはコンパイル時に作成されるため、SEARCHLISTもREPLACEMENTLISTも二重引用符の補間を受けないことに注意してください。つまり、変数を使用する場合は、eval()を使用する必要があります。

eval "tr/$oldlist/$newlist/";

(ソース)

于 2010-08-01T15:59:47.880 に答える
4

変数の使用を許可していないので、私はこれらの線に沿って何かを提案します(他の懸念を引き起こすtr///を使用するのではなく):eval

sub strip_invalid {
    my $str = shift;
    my $chars = quotemeta(join '', @_);
    $str =~ s/[$chars]//g;
    return $str;
}

またtr///、削除オプションがあるため、削除するすべての文字を繰り返す必要はありません。例えば:

$str =~ tr/aeiou//d; # Delete all vowels from $str
于 2010-08-01T16:05:43.273 に答える
2

trで削除するには、/dフラグを指定する必要があります。それ以外の場合は、検索リストに基づいて置換リストがデフォルトになります(したがって、カウントまたは圧縮するだけです)。

また、trは変数補間をサポートしていません。

trを使用するには、次のようなことを行う必要があります。

sub strip_invalid {
    my ($str, @chars) = @_;

    my $strip = quotemeta join '', @chars;
    eval "\$str =~ tr/$strip//d";

    return $str;
}
于 2010-08-01T16:55:51.393 に答える