perl 的 utf8 问题

perl 的 utf8 问题

如 perl 语言本生一样, perl 的 utf8 支持有很多奇技淫巧和陷阱,这里简单说几条

1、内部函数的 utf8 化

让诸如 split substr, length 等涉及字符串的函数在 utf8 字符串的语境下工作。


use utf8;


2、文件描述符的 utf8 模式


binmode STDIN, ':utf8';
binmode STDOUT, ':utf8';
# 引用也一样
binmode $in, ':utf8';
binmode $out, ':utf8';


输出方向避免 "Wide character in print" 错误
输入方向让读入的字符串默含有 utf8 标记。

3、命令行参数的utf8化


utf8::is_utf8($_) || utf8::decode($_) for @ARGV;


默认读入的 @ARGV 参数没有 utf8 标记,你可以使用下面代码分别测试使用和不使用上面的代码的不同效果:

print join("\n", split(//, join(undef, @ARGV)));


4、常用函数的 utf8 陷阱

比如 readlink, Cwd::realpath, File::Glob::bsd_glob 等返回的字符串没有 utf8 标记,可以用类似下面的方式解决:

# workaround for functions that don't cope with utf8 well
sub to_utf8($) {
    my ($str) = @_;
    utf8::decode($str) unless utf8::is_utf8($str);
    return $str;
}
sub readlink_utf8($) {
    my ($filename) = @_;
    return to_utf8(readlink($filename));
}
sub realpath($) { return to_utf8(Cwd::realpath(@_)); }
sub bsd_glob($) { return map {to_utf8($_)} File::Glob::bsd_glob(@_); }


这里最糟糕的问题在于,你不知道别人的库提供的函数返回的字符串是否有 utf8 标记,如果你在编程中遇到正则匹配分割以及其他操作后有乱码的现象,不妨考虑考虑是不是因为这个原因。


参考文档:

Unicode-processing issues in Perl and how to cope with it : http://ahinea.com/en/tech/perl-unicode-struggle.html
太棒了,收藏起来了。
nice
算好文了
很多不知道的