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///不允许使用变量,我会建议一些类似的东西(而不是 using 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 回答