• Publicidad

44 recetas para trabajar con Unicode en Perl

Así que programas sin strict y las expresiones regulares son otro modo de hablar. Aquí encontrarás respuestas de nivel avanzado, no recomendable para los débiles de corazón.

Re: 44 recetas para trabajar con Unicode en Perl

Notapor explorer » 2012-05-26 08:37 @401

℞ 30: Extraer por grafema en lugar de por código de carácter (exp.reg.)

Recuerde que Unicode define un grafema como "lo que un usuario piensa que es un carácter". Un código de carácter es un valor entero en el espacio de código Unicode. Mientras que ASCII combina los dos, el uso efectivo de Unicode respeta la diferencia entre caracteres visibles por el usuario y sus representaciones.

Use el metacarácter de exp.reg. \X cuando necesite extraer grafemas de una cadena en lugar de códigos de carácter:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.  # coincide y captura los cinco primeros grafemas
  2.  my ($cinco_primeros) = $cadena =~ /^ ( \X{5} ) /x;
Coloreado en 0.005 segundos, usando GeSHi 1.0.8.4


Artículo original (en inglés)
JF^D Perl Programming Language
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 12784
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Publicidad

Re: 44 recetas para trabajar con Unicode en Perl

Notapor explorer » 2012-05-26 09:21 @431

℞ 31: Extraer por grafema en lugar de por código de carácter (substr)

El Anexo n.º 29 del Estándar Unicode habla de los límites entre agrupaciones de grafemas -lo que los usuarios pueden percibir como "caracteres"-. El módulo CPAN Unicode::GCString le permite tratar una cadena Unicode como una secuencia de agrupaciones de grafemas.

Mientras que puede usar \X para extraer grafemas en una exp.reg. (℞ 30), Unicode::GCString ofrece un método substr() para extraer una serie de agrupaciones de grafemas:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.  # cpan -i Unicode::GCString
  2.  use Unicode::GCString;
  3.  
  4.  my $gcs            = Unicode::GCString->new($str);
  5.  my $cinco_primeros = $gcs->substr(0, 5);
Coloreado en 0.005 segundos, usando GeSHi 1.0.8.4

El módulo también ofrece un interfaz para iterar por las agrupaciones de grafemas que hay dentro de una cadena.

Artículo original (en inglés)
JF^D Perl Programming Language
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 12784
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: 44 recetas para trabajar con Unicode en Perl

Notapor explorer » 2012-05-30 17:30 @771

℞ 32: Invertir una cadena por sus grafemas

Debido a que los bytes y los caracteres no son isomórficos en Unicode -y que lo que quizás vea como un carácter visible para el usuario (un grafema) no es necesariamente un único código de carácter en una cadena Unicode- debe tener cuidado en cada operación de cadena de las diferencias entre códigos de carácter y grafemas.

Considere la función integrada de Perl reverse(). Invertir una cadena por códigos de carácter mezcla los diacríticos, convirtiendo erróneamente crème brûlée en éel̂urb em̀erc en lugar de eélûrb emèrc. Así que, en su lugar, invierta por grafema.

Como primera opción, use el metacarácter de exp. reg. de Perl \X (℞ 29) para extraer grafemas de una cadena, y luego invierta esa lista:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.  $str = join("", reverse $str =~ /\X/g);
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4

Otra opción, use Unicode::GCString para tratar una cadena como una secuencia de grafemas, no códigos de carácter:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.  use Unicode::GCString;
  2.  $str = reverse Unicode::GCString->new($str);
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4

Estas dos aproximaciones funcionan correctamente sin importar en qué normalización se encuentre la cadena. Recuerde que \X funciona mejor solo en y a partir de Perl 5.12.

Artículo original (en inglés)
JF^D Perl Programming Language
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 12784
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: 44 recetas para trabajar con Unicode en Perl

Notapor explorer » 2012-05-31 09:19 @429

℞ 33: Longitud de la cadena en grafemas

Si solo quiere aprender una cosa sobre Unicode, recuerde esto: los caracteres no son bytes, que no son grafemas, que no son códigos de carácter. Un símbolo visible para el usuario (un grafema) puede estar compuesto de múltiples códigos de carácter. Múltiples combinaciones de códigos de carácter pueden producir los mismos grafemas visibles para el usuario.

Para que quede completamente claro, sea cuidadoso y específico sobre lo que está intentando hacer en cada nivel.

Como ejemplo concreto, la cadena brûlée tiene seis grafemas pero también hasta ocho códigos de carácter. Ahora suponga que quiere obtener su longitud. ¿Qué significa longitud? Si su cadena ha sido normalizada a una forma de un-grafema-por-código-de-carácter, length() es único y el mismo, pero considere esto:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.  use Unicode::Normalize;
  2.  my $str = "brûlée";
  3.  say length $str;
  4.  say length NFD( $str );
Coloreado en 0.005 segundos, usando GeSHi 1.0.8.4

Para medir la longitud de una cadena contando por grafemas, pero no por códigos de carácter:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.  my $str   = "brûlée";
  2.  my $count = 0;
  3.  while ($str =~ /\X/g) { $count++ }
Coloreado en 0.005 segundos, usando GeSHi 1.0.8.4

De otra forma, (o en versiones anteriores de Perl), el módulo de CPAN Unicode::GCString es muy útil:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.  use Unicode::GCString;
  2.  my $gcs   = Unicode::GCString->new($str);
  3.  my $count = $gcs->length;
Coloreado en 0.005 segundos, usando GeSHi 1.0.8.4


Artículo original (en inglés)
JF^D Perl Programming Language
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 12784
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: 44 recetas para trabajar con Unicode en Perl

Notapor explorer » 2012-06-01 14:34 @649

℞ 34: Impresión de columnas de ancho fijo en Unicode

Las funciones integradas de Perl printf, sprintf y format, creen que todos los códigos de carácter ocupan una columna de impresión, pero muchos códigos de carácter toman 0 o 2. Si usa alguna de estas funciones para alinear texto, puede encontrarse con que la idea de que tiene Perl del ancho de cualquier código de carácter no coincide con lo que usted cree que debería ser.

El método columns() del módulo Unicode::GCString considera el ancho de cada código de carácter y devuelve el número de columnas que la cadena ocupará. Use esto para determinar el ancho en pantalla de una cadena Unicode.

Para mostrar que la normalización no hace ninguna diferencia en el número de columnas de una cadena, imprimiremos de ambas formas:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.  # cpan -i Unicode::GCString
  2.  use Unicode::GCString;
  3.  use Unicode::Normalize;
  4.  
  5.  my @palabras = qw/crème brûlée/;
  6.  @palabras    = map { NFC($_), NFD($_) } @words;
  7.  
  8.  for my $cadena (@palabras) {
  9.      my $gcs  = Unicode::GCString->new($cadena);
  10.      my $cols = $gcs->columns;
  11.      my $rell = " " x (10 - $cols);
  12.      say $cadena, $rell, " |";
  13.  }
Coloreado en 0.006 segundos, usando GeSHi 1.0.8.4

... genera esto, para mostrar que rellena correctamente sin importar qué normalización sea:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
 crème      |
 crème      |
 brûlée     |
 brûlée     |
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Artículo original (en inglés)
JF^D Perl Programming Language
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 12784
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: 44 recetas para trabajar con Unicode en Perl

Notapor explorer » 2012-06-01 18:58 @832

℞ 35: Cotejo Unicode

Ordenar texto en puro ASCII es fácil: si sabes la canción del alfabeto, puedes hacerlo. Ordenar datos Unicode es mucho más difícil: las reglas por cada carácter especifican su relación con los otros caracteres. Estas reglas de cotejo guían la ordenación y comparación de datos con respecto al tamaño de caja, marcas de acentos, ancho del carácter, y otras propiedades Unicode.

Una simple ordenación de datos basados en los códigos de carácter Unicode que estén fuera del rango alfabético de los caracteres ASCII, no produce nada sensato. Una ordenación sensible, de otra forma, debe respetar el Algoritmo de Cotejo Unicode (Unicode Collation Algorithm -UCA-). El módulo de CPAN Unicode::Collate implementa UCA. Su uso es muy simple:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.  use Unicode::Collate;
  2.  my $col  = Unicode::Collate->new();
  3.  my @list = $col->sort(@old_list);
  4.  
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4

Vea también el programa ucsort del módulo Unicode::Tussle para ver un interfaz apropiado para la línea de comandos para este módulo.

Artículo original (en inglés)
JF^D Perl Programming Language
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 12784
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: 44 recetas para trabajar con Unicode en Perl

Notapor explorer » 2012-06-05 05:14 @259

℞ 36: Ordenación Unicode independiente del tamaña de caja y de las tildes

El Algoritmo de Cotejo Unicode (UCA) define varios niveles de forzado de cotejo en los que puede especificar ciertas propiedades como relevantes o irrelevantes en la ordenación por cotejo. En términos simples: puede usar el forzado de cotejo para indicar una ordenación de acuerdo a UCA para ignorar el tamaño de caja o los diacríticos.

En Perl, use el módulo Unicode::Collate para realizar su ordenación. Para ordenar cadenas Unicode mientras ignora el tamaño de caja y los diacríticos -para examinar solo los caracteres básicos- use una fuerza de cotejo de nivel 1:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.  use Unicode::Collate;
  2.  my $col = Unicode::Collate->new(level => 1);
  3.  my @list = $col->sort(@old_list);
Coloreado en 0.005 segundos, usando GeSHi 1.0.8.4

El nivel 2 añade comparaciones de diacríticos al algoritmo de ordenación. Nivel 3 añade ordenación por tamaño de caja. Nivel 4 añade una comparación por desempate, con tanto detalle que la mayor parte de la gente no querrá ni saberlo. Nivel 4 es el valor por defecto.

Artículo original (en inglés)
JF^D Perl Programming Language
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 12784
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: 44 recetas para trabajar con Unicode en Perl

Notapor explorer » 2012-06-06 15:41 @695

℞ 37: Cotejo Regional Unicode

Como ya se ha visto, la ordenación del Unicode (℞ 35) respeta las propiedades de los caracteres Unicode. No puede ordenar por código de carácter y esperar obtener resultados correctos, ni incluso si solo tiene puro ASCII.

El mundo es un lugar complicado. Algunas configuraciones regionales tiene sus propias reglas especiales de ordenación.

El módulo Unicode::Collate::Locale ofrece el método sort() que soporta reglas específicas de las configuraciones regionales:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.  use Unicode::Collate::Locale;
  2.  
  3.  my $col  = Unicode::Collate::Locale->new(locale => "de__phonebook");
  4.  my @list = $col->sort(@old_list);
Coloreado en 0.005 segundos, usando GeSHi 1.0.8.4

Este módulo es parte de la distribución principal de Perl 5 a partir de Perl 5.12. Si está usando una versión anterior de Perl, instale la distribución Unicode::Collate para poder usarlo.

El programa ucsort mencionado en la receta 35 acepta un parámetro --locale.

Artículo original (en inglés)
JF^D Perl Programming Language
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 12784
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: 44 recetas para trabajar con Unicode en Perl

Notapor explorer » 2012-06-08 17:49 @784

℞ 38: Haciendo que cmp trabaje con texto en lugar de con códigos de carácter

Incluso con la característica "unicode_strings" de Perl 5.12, algunas operaciones principales de Perl no funcionan como se espera cuando manejan cadenas Unicode, de forma predeterminada. Por ejemplo, ¿cómo sabe el operador cmp que sus argumentos son octetos, códigos de carácter grandes, o grafemas o debe tener en cuenta un cotejo específico?

Dónde se podría escribir
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.  @srecs = sort {
  2.      $b->{AGE}   <=>  $a->{AGE}
  3.                  ||
  4.      $a->{NAME}  cmp  $b->{NAME}
  5.  } @recs;
Coloreado en 0.005 segundos, usando GeSHi 1.0.8.4

... una comparación basada en Unicode debería, en su lugar, usar Unicode::Collate:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.  my $coll = Unicode::Collate->new();
  2.  for my $rec (@recs) {
  3.      $rec->{NAME_key} = $coll->getSortKey( $rec->{NAME} );
  4.  }
  5.  @srecs = sort {
  6.      $b->{AGE}       <=>  $a->{AGE}
  7.                      ||
  8.      $a->{NAME_key}  cmp  $b->{NAME_key}
  9.  } @recs;
Coloreado en 0.005 segundos, usando GeSHi 1.0.8.4

El método getSortKey() devuelve una forma de clave de ordenación apropiada que respeta el cotejo (y el nivel de cotejo) para una cadena Unicode dada. cmp puede manejar estas claves de forma efectiva.

Artículo original (en inglés)
JF^D Perl Programming Language
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 12784
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: 44 recetas para trabajar con Unicode en Perl

Notapor explorer » 2012-06-08 17:59 @791

℞ 39: Comparación insensible al tamaño de caja y a los diacríticos

Como habrá notado hasta ahora, muchas cadenas Unicode tienen múltiples posibles representaciones. Comparar dos cadenas Unicode por su igualdad requiere mucho más que sólo comparar sus códigos de carácter. No solo debe tener en cuenta las múltiples representaciones, sino que además debe decidir qué tipos de diferencias son significativas: ¿tiene que preocuparse por el tamaño de caja de los caracteres individuales? ¿Qué hay de la presencia o ausencia de las tildes?

Use un objeto cotejador para comparar texto Unicode de carácter en carácter en lugar de por código de carácter. Para realizar las comparaciones sin preocuparse por el tamaño de caja o las diferencias en las tildes, elija el apropiado nivel de comparación. El método eq() del módulo Unicode::Collate ofrece esta comprobación de igualdad, personalizable y compatible con Unicode:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.  use Unicode::Collate;
  2.  my $es = Unicode::Collate->new(
  3.      level         => 1,
  4.      normalization => undef
  5.  );
  6.  
  7.  # ahora ambos son ciertos:
  8.  $es->eq("García",  "GARCIA" );
  9.  $es->eq("Márquez", "MARQUEZ");
Coloreado en 0.005 segundos, usando GeSHi 1.0.8.4


Artículo original (en inglés)
JF^D Perl Programming Language
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 12784
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

AnteriorSiguiente

Volver a Avanzado

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 0 invitados

cron