如果您的脚本和输入文件使用相同的编码进行编码,则您的代码将按原样运行。
$ cat>test.html
ùmbrella ùnder ùùùùù ùtters
$ perl a.pl
$ cat out/test.html
umbrella under uuuuu utters
你的程序是越野车,虽然。假设我们正在谈论UTF-8。Perl的实际看到
$str =~ s/\xC3\xB9/u/g;
虽然这并没有那么糟糕,想象一下,如果你有
$str =~ s/[ùú]/u/g;
的Perl会认为这是
$str =~ s/[\xC3\xB9\xC3\xBA]/u/g;
这会变成ù
(C3 B9
)为uu
和é
(C3 A9
)插入u<garbage>
。
对于Perl来识别程序中的任何非ASCII字符,您必须确保程序文件使用UTF-8进行编码,并且您需要在文件顶部添加use utf8;
。随着use utf8;
,Perl中看到
$str =~ s/[ùú]/u/g;
或者说
$str =~ s/[\xF9\xFA]/u/g; # F9 and FA are the Unicode Code Points for ù and ú
然而,增加use utf8;
只是解决方案的一半。我们改变了Perl看到正则表达式的方式,但我们没有改变$str
,所以它们不可能再匹配。我们比较ù
(C3 B9
)与ù
(F9
)Unicode代码点编码
始终解码你的投入。始终对输出进行编码。
我们已经解码的一个输入(程序本身)。现在我们需要对文件的内容做同样的事情。
同样,我们需要编码输出。这不仅包括文件的内容,还包括输出到STDERR的警告。
大部分由
use open ':std', ':encoding(UTF-8)';
做它增加了一个编码层STDIN,STDOUT和STDERR,并设置编译的词法范围内打开文件的默认编码层。
#!/usr/bin/perl
use utf8;
use open ':std', ':encoding(UTF-8)';
use strict;
use warnings;
my $in_qfn = 'test.html';
my $out_qfn = 'out/test.html';
# :encoding(UTF-8) is added by "use open".
open(my $in_fh, '<', $in_qfn) or die("Can't open \"$in_qfn\": $!\n");
open(my $out_fh, '>', $out_qfn) or die("Can't create \"$out_qfn\": $!\n");
while (<$in_fh>) {
s/[ùú]/u/g;
print($out_fh $_);
}
如果使用文件::嘟嘟地喝,你需要告诉它的文件进行解码(或自己对其进行解码),因为它open
不在use open
的范围。
#!/usr/bin/perl
use utf8;
use open ':std', ':encoding(UTF-8)';
use strict;
use warnings;
use File::Slurp qw(read_file write_file);
my $in_qfn = 'test.html';
my $out_qfn = 'out/test.html';
my $file = read_file($in_qfn, binmode => ':encoding(UTF-8)');
$file =~ s/[ùú]/u/g;
write_file($out_qfn, { binmode => ':encoding(UTF-8)' }, $file);
@siam的感谢!我不得不添加“使用utf8;”顶部还有 – Xavia
@siam:你在想Python!这只是Perl中的一个评论。 – Borodin
[档案::嘟嘟地喝坏了,错了。(http://blogs.perl.org/users/leon_timmermans/2015/08/fileslurp-is-broken-and-wrong.html) – ThisSuitIsBlackNot