Здесь есть несколько проблем.Они в основном соответствуют синтаксису вашего оператора tr/../../
.Это должно быть так:
$line =~ tr/CHARS/CHARS/;
У вас $line
в неправильном месте, и вы используете обратную косую черту вместо прямой косой черты (вы можете использовать прямую косую черту в качестве разделителя в операторе tr/.../.../
, но помните, что они имеют особое значение в строках в двойных кавычках.
Кажется, это делает то, что вы хотите (я переключился на использование внутреннего дескриптора файла DATA
для простоты тестирования.
#!/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
Я, очевидно, не знаю точно, с какими символами вы здесь работаете, но похоже, вы могли бы найти Text :: Unidecode полезным.
Обновление: Стоит также отметить, что выражение tr/.../.../
все еще не совсем верно (хотя оно работает). Если вы напечатаете $statement
, вы увидите, что оно дает:
$line =~ tr/Ñ Ê/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/";