Considere el siguiente programa:
lhp@nereida:~/Lperl/src/testing$ cat -n useutf8_1.pl 1 #!/usr/local/bin/perl -w 2 use strict; 3 4 my $x = 'áéíóúñ€'; 5 print "$x\n"; 6 print length($x)."\n";Cuando lo ejecutamos obtenemos la salida:
lhp@nereida:~/Lperl/src/testing$ useutf8_1.pl áéíóúñ€ 15Perl tiene dos modos de procesamiento de datos: el modo byte y el modo carácter. El modo por defecto es el modo byte. Este modo es conveniente cuando se trabaja con ficheros binarios (p. ej. una imagen JPEG) y con texto codificado con un código que requiere un sólo byte por carácter como es el caso de Latin 1.
En efecto, la cadena 'áéíóúñ€'
- que es una cadena unicode codificada en UTF-8 -
tiene una longitud de 15 bytes. El asunto es que
no es lo mismo la longitud en bytes que la longitud en caracteres cuando nos salimos de ASCII
y Latin1. Si queremos
que length devuelva la longitud en caracteres usemos utf8 :
lhp@nereida:~/Lperl/src/testing$ cat -n useutf8_2.pl 1 #!/usr/local/bin/perl -w 2 use strict; 3 use utf8; 4 5 my $x = 'áéíóúñ€'; 6 print "$x\n"; 7 print length($x)."\n";Al ejecutar obtenemos la longitud en caracteres:
lhp@nereida:~/Lperl/src/testing$ useutf8_2.pl Wide character in print at ./useutf8_2.pl line 6. áéíóúñ€ 7Ahora
length
retorna la longitud en caracteres.
Obsérvese el mensaje de advertencia. Si queremos asegurar el buen funcionamiento
de la salida por STDOUT
con caracteres codificados en UTF-8
debemos
llamar a binmode sobre STDOUT
con la capa ':utf8'
:
lhp@nereida:~/Lperl/src/testing$ cat -n useutf8_3.pl 1 #!/usr/local/bin/perl -w 2 use strict; 3 use utf8; 4 binmode(STDOUT, ':utf8'); 5 6 my $x = 'áéíóúñ€'; 7 print "$x\n"; 8 print length($x)."\n";El mensaje de advertencia desaparece:
lhp@nereida:~/Lperl/src/testing$ useutf8_3.pl áéíóúñ€ 7Usando la opción
-C
del intérprete Perl se puede conseguir el mismo resultado:
lhp@nereida:~/Lperl/src/testing$ perl useutf8_1.pl áéíóúñ€ 15 lhp@nereida:~/Lperl/src/testing$ perl -Mutf8 -COE useutf8_1.pl áéíóúñ€ 7
Lea perldoc
perlrun
para mas información sobre estas
opciones:
As of 5.8.1, the "-C" can be followed either by a number or a list of option letters. The letters, their numeric values, and effects are as follows; listing the letters is equal to summing the numbers. I 1 STDIN is assumed to be in UTF-8 O 2 STDOUT will be in UTF-8 E 4 STDERR will be in UTF-8 S 7 I + O + E i 8 UTF-8 is the default PerlIO layer for input streams o 16 UTF-8 is the default PerlIO layer for output streams D 24 i + o A 32 the @ARGV elements are expected to be strings encoded in UTF-8 L 64 normally the "IOEioA" are unconditional, the L makes them conditional on the locale environment variables (the LC_ALL, LC_TYPE, and LANG, in the order of decreasing precedence) -- if the variables indicate UTF-8, then the selected "IOEioA" are in effect
En Perl las cadenas tienen un flag que indica si la representación interna
de la cadena es utf-8.
La función is_utf8
de utf8
permite conocer
si una cadena esta almacenada internamente como utf-8:
pl@nereida:~/Lperltesting$ cat -n is_utf8.pl 1 #!/usr/local/lib/perl/5.10.1/bin/perl5.10.1 -w -COE 2 use strict; 3 use utf8; 4 5 my $x = 'áéíóúñ€'; 6 my $y = 'abc'; 7 my $z = 'αβγδη'; 8 print "$x is utf8\n" if utf8::is_utf8($x); 9 print "$y is utf8\n" if utf8::is_utf8($y); 10 print "$z is utf8\n" if utf8::is_utf8($z);Al ejecutar produce la salida:
pl@nereida:~/Lperltesting$ ./is_utf8.pl áéíóúñ€ is utf8 αβγδη is utf8
Casiano Rodríguez León