【问题标题】:Correct and portable utf8 filename normalization正确且可移植的 utf8 文件名规范化
【发布时间】:2012-06-07 02:29:29
【问题描述】:

还有一个 perl/utf8 问题:

代码:

use 5.012;
use utf8;
use strict;
use warnings;
use feature qw(unicode_strings);

use open qw(:std :utf8);
use Encode qw(encode decode);
use charnames qw(:full);
use Unicode::Normalize qw(NFD NFC);

my $name = "\N{U+00C1}";        # Á (UPPERCASE A WITH ACUTE)

opendir(my $dh, ".") || die "error opendir";
while(readdir $dh) {
    say "ENC-OK" if      decode('UTF-8', $_)   =~ $name; #never true
    say "NFC-OK" if NFC( decode('UTF-8', $_) ) =~ $name; #true
}
closedir $dh;

上面的代码将为每个文件名中包含Á 的文件打印NFC-OK。但永远不会在 NFD 编码的文件系统上打印 ENC-OK,因为 opendir 永远不会以 \x00C1 的形式返回 Á,而是 "A"、"accent"...

问题:如何为任何操作系统正确编写上述代码?

【问题讨论】:

    标签: perl utf-8 portability


    【解决方案1】:

    更具体地说,

    NFC( decode('UTF-8', $_) ) =~ quotemeta( NFC( $name ) )
    

    NFD( decode('UTF-8', $_) ) =~ quotemeta( NFD( $name ) )
    

    适用于每个文件名,无论其形式如何。

    ...好吧,只要它是 UTF-8 编码的。 Windows 上不会出现这种情况,除非使用 chcp 65001。

    【讨论】:

    • 已更改答案以匹配问题。
    • 使用模式匹配是没有意义的。只需使用 eq 并跳过 quotameta()ing。
    猜你喜欢
    • 2013-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-24
    • 2018-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多