在音译操作符中使用变量

时间:2012-05-02 23:47:13

标签: regex perl

这是一个愚蠢的问题;我需要这个更复杂的东西但是让它变得简单:

$i = quotemeta 'A';
$line =~ tr/a-z/$i-Z/;

这是一个愚蠢的替代,这应该把小写字母变成大写字母,但我尝试过的东西不起作用。

好的,所以我看到这带来了很多混乱,真正的代码应该是:

$line =~ tr/A-Z/F-ZA-E/;

应该是Caesers Chiper algorhytm。如果你想用固定数量的字母改变它,这可以正常工作,但我需要一个变量,所以我可以根据需要改变它。但我想发送eval 日Thnx

P.S。另外,为什么不// s /使用范围?

4 个答案:

答案 0 :(得分:4)

请注意,对于tr///,您只能使用文字字符,而不能使用变量。因此,tr/a-z/$i-Z/不起作用,您必须使用tr/a-z/A-Z/。在perldoc perlop中,您可以阅读有关tr///的更多信息,并找到有关插值或缺少插值的说明。

将字符串转换为大写字母,但还有其他方法。您可以使用uc函数或正则表达式转义序列\U(大写)和\L(小写)。 E.g:

my $str = 'a';
my $uppercase = uc $str;

正则表达式:

my $str = 'abcdef';
$str =~ s/([a-z]+)/\U$1/;  # $str is now 'ABCDEF'

tchrist指出[a-z]应该写成\p{CWU},其中包括受案例影响的所有字符。

<强>更新

如果您正在尝试创建某种动态编码功能,我建议使用一个带有参数的子程序,并手动移动字符。

sub foo {
    my ($str, $num) = @_;  # num is how many characters to shift the alphabet
    my @in  = 'A' .. 'Z';
    my @out = @in[$num .. $#in, 0 .. $num-1];
    my %out = map { $in[$_] => $out[$_] } 0 .. $#in;
    $str =~ s#(.)# $out{$1} // $1 #eg;  # if key does not exist, use org
    return $str;
}

请注意,它区分大小写,但您可以为小写添加键以解决此问题。

答案 1 :(得分:4)

如果你真的需要tr,你可以使用eval:

$i = quotemeta 'A'
eval("\$line =~ tr/a-z/$i-Z/;");

答案 2 :(得分:2)

遗憾的是,你的榜样并不好; tr运算符不接受任何变量插值(在任一半中)。如果您实际使用的是tr,那么除非您使用eval,否则您将失去运气,这是不推荐的。如果您没有使用tr,请向我们展示实际代码,以便我们了解正在发生的情况并提供更多建议。

<强>更新

这个怎么样?

my %map;
@map{'A'..'Z'} = ('F'..'Z','A'..'E');
s/[A-Z]/$map{$&}/g;

不确定它是否仍然存在,但是由于性能损失可能会不惜一切代价避免$&。你可以很容易地做到这一点:

s/([A-Z])/$map{$1}/g;

答案 3 :(得分:0)

tr不适用于变量;改为使用s ///(替换)。