Perl 对数组使用tr

Perl 对数组使用tr,perl,tr,Perl,Tr,我试图使用tr函数指定两个数组,作为to和from集。翻译似乎不起作用,或者我没有正确理解。 我是perl新手,所以如果我做错了什么,请告诉我 我加载阵列的方式如下(我知道这部分工作正常): 打开我的$fh,你的$statement有点不对劲,正常的形式是$line=~tr/a/b/,对吗?所以应该是这样的: my $statement = "\$line =~ tr/\Q@from_set\E/\Q@to_set\E/;" $line =~ tr/CHARS/CHARS/; 在求值过程中,

我试图使用tr函数指定两个数组,作为to和from集。翻译似乎不起作用,或者我没有正确理解。 我是perl新手,所以如果我做错了什么,请告诉我

我加载阵列的方式如下(我知道这部分工作正常):
打开我的$fh,你的
$statement
有点不对劲,正常的形式是
$line=~tr/a/b/
,对吗?所以应该是这样的:

my $statement = "\$line =~ tr/\Q@from_set\E/\Q@to_set\E/;"
$line =~ tr/CHARS/CHARS/;

在求值过程中,
\$line
应保持为一个变量,因此将其转义为
\$line
@from\u set
@to\u set
的内容应该插入到
$语句中,因此它们没有
\

,这里有一些问题。它们主要围绕
tr/../../
语句的语法。应该是这样的:

my $statement = "\$line =~ tr/\Q@from_set\E/\Q@to_set\E/;"
$line =~ tr/CHARS/CHARS/;
$line
的位置不正确,使用的是反斜杠而不是正斜杠(可以在
tr/../../../
语句中使用正斜杠作为分隔符,但请记住它们在双引号字符串中有特殊含义)

这似乎是您想要的(为了便于测试,我已经切换到使用内部
数据
文件句柄)

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';
use utf8;

my @from;
my @to;

while (<DATA>) {
  chomp;
  my @conv = split;
  push @from, $conv[0];
  push @to,   $conv[1];
}

my $line = 'PICAÑA';

my $statement = "\$line =~ tr/@from/@to/";

eval $statement;

say $line;

__DATA__
Ñ N
Ê E
这个额外的空间来自这样一个事实:Perl在双引号字符串中插入数组元素时,会在数组元素之间放置一个空格。如果您愿意,可以通过将
$“
设置为空字符串来解决这个问题

更新2:

仔细考虑之后,我想我根本不会使用数组。为什么不使用标量呢

my $from = '';
my $to   = '';

# And then, in the loop...

$from .= $conv[0];
$to   .= $conv[1];

# And later still...

my $statement = "\$line =~ tr/$from/$to/";

我假设你选择了
tr///
,因为它比
s///
快。如果是这样,每次做翻译时使用
eval
是违背目的的。如果你使用
eval
一次,但执行多次翻译,那么速度会更快

除了可以多次使用编译后的
tr///
之外,下面还修复了Perl语法错误和bug:

另一方面,如果你只做了一次音译,那么你使用
tr///
会让你的生活变得更加复杂,并且毫无意义地减慢你的程序的速度。请改用
s///

my %map; @map{@from_set} = @to_set;
my $from_set = join '', @from_set;
my $re = qr/([\Q$from_set\E])/;

my $output = $input =~ s/$re/$map{$1}/gr;

从Perl Mongers中,如果您想要防止斜杠插入,您应该像这样使用quotemeta或使用@ikegami解决方案:

eval sprintf "tr/%s/%s/", map quotemeta, $oldlist, $newlist;

欢迎访问该网站!查看和,了解更多有关提问的信息,这些问题将吸引高质量的答案。如果有人提问,您可以添加更多信息。例如,添加
char\u convert
文件的示例将使问题更加完整。但是,由于您已经有了答案,可能不需要这样做在这种情况下:).vlumi,我认为在计算
$statement
之前,您可能还需要
local$”='''
,具体取决于Perl版本。在我的测试系统上,
my@a=1,2,3;“@a”
的计算结果为
“1 2 3”
,而不是
“123”
,因为默认的
$”
”“
。请参阅。@cxw只要两边的空格都在同一个位置,这实际上并不重要,尽管这样会更安全。甚至可以将它们正确地连接到标量值中,并将它们放入求值语句中…@ikegami Fixed,我希望…?以前从未见过它将其用于数组,但没有理由不这样做。我测试了它以确定(
perl-E'@a=qw(| |);say“\Q@a“'
)注入错误!使用
“tr/\Q$from\E/\Q$to\E/”
您可以使用连接函数连接列表,即my$from=join(“”,@from\u set)@池上:
\Q
在音译中没有效果。1)这不是在代码中留下错误的借口,2)我不建议你在音译文字中使用它;我建议您使用双引号字符串文字。谢谢。帮助很大。正如我所说,我是perl新手,所以我会犯“愚蠢”的错误。但这就是我们学习的方式。我刚刚修复了一个bug。
eval sprintf "tr/%s/%s/", map quotemeta, $oldlist, $newlist;