这是一个愚蠢的问题;我需要这个更复杂的东西但是让它变得简单:
$i = quotemeta 'A';
$line =~ tr/a-z/$i-Z/;
这是一个愚蠢的替代,这应该把小写字母变成大写字母,但我尝试过的东西不起作用。
好的,所以我看到这带来了很多混乱,真正的代码应该是:
$line =~ tr/A-Z/F-ZA-E/;
应该是Caesers Chiper algorhytm。如果你想用固定数量的字母改变它,这可以正常工作,但我需要一个变量,所以我可以根据需要改变它。但我想发送eval 日Thnx
P.S。另外,为什么不// s /使用范围?
答案 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 ///(替换)。