2012-06-01 20 views
12

otra pregunta Perl/UTF-8:correcta y portátil normalización utf8 nombre

Código:

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; 

El código anterior imprimir NFC-OK para cada archivo que contiene Á en el nombre de archivo. Pero nunca imprimirá ENC-OK, en sistema de archivos codificado NFD, porque el opendir nunca devuelve Á en la forma \ x00C1, pero "A", "acento" ...

Pregunta: cómo escribir correctamente el código anterior para cualquier sistema operativo?

Respuesta

2

Más específicamente,

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

y

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

obras para cada nombre de archivo reguardless de su forma.

... Bueno, siempre y cuando esté codificado en UTF-8. Ese no será el caso en Windows, excepto tal vez cuando se utiliza chcp 65001.

+0

Se ha cambiado la respuesta para que coincida con la pregunta. – ikegami

+0

No tiene sentido usar una coincidencia de patrón. Simplemente use un 'eq' y omita el quotameta() ing. – tchrist

+0

@tchrist, no, no es lo mismo, y no funcionaría. – ikegami