2010-08-01 72 views
2

编辑:TR ///不支持变量插值,所以我s/\Q$_\E//g;代替Perl的TR ///没有做什么,我想

或者,更有可能去了,我没有做正确的事情.. 。

我有以下代码:

#!/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///通过map ......我有什么错删除@invalid的人物? (顺便说一句,它使用正则表达式)。

回答

7

Perl的tr功能doesn't support variables

请注意,因为翻译表是在编译时生成的,所以SEARCHLIST和REPLACEMENTLIST都不受双引号内插。这意味着,如果你想使用的变量,你必须使用一个eval():

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

(Source)

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 
2

要用tr删除,您需要指定/ d标志。否则,它默认基于搜索列表的替换列表(所以只是计数或压缩)。

而tr不支持可变插值。

要使用TR,你需要做这样的事情:

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

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

    return $str; 
}