Pregunta

Estoy buscando una manera de hacer coincidir solo los caracteres completamente compuestos en una cadena Unicode.

¿Es [: print:] dependiente de la configuración regional en cualquier implementación de expresión regular que incorpore esta clase de caracteres? Por ejemplo, ¿coincidirá con el carácter japonés '?', ya que no es un carácter de control, o es [: print:] siempre serán códigos ASCII 0x20 a 0x7E?

¿Hay alguna clase de caracteres, incluidos los RE de Perl, que pueda usarse para hacer coincidir algo que no sea un carácter de control? Si [: print:] incluye solo caracteres en el rango ASCII, asumiría que [: cntrl:] también lo hace.

¿Fue útil?

Solución

echo あ| perl -nle 'BEGIN{binmode STDIN,":utf8"} print"[<*>

Esto funciona principalmente, aunque genera una advertencia sobre un carácter ancho. Pero le da la idea: debe asegurarse de que está tratando con una cadena real de Unicode (verifique utf8 :: is_utf8). O simplemente consulte perlunicode en todo - todo el tema todavía hace girar mi cabeza.

]"; print /[[:print:]]/ ? "YES" : "NO"'

Esto funciona principalmente, aunque genera una advertencia sobre un carácter ancho. Pero le da la idea: debe asegurarse de que está tratando con una cadena real de Unicode (verifique utf8 :: is_utf8). O simplemente consulte perlunicode en todo - todo el tema todavía hace girar mi cabeza.

Otros consejos

Creo que no quieres o necesitas locales para eso, sino Unicode. Si ha decodificado una cadena de texto, \ w coincidirá con los caracteres de las palabras en cualquier idioma, \ d no solo coincidirá con 0..9 sino con todos Dígito Unicode, etc. En expresiones regulares puede consultar las propiedades de Unicode con \ p {PropertyName} . Particularmente interesante para usted podría ser \ p {Imprimir} . Aquí hay una lista de todas las propiedades de caracteres Unicode disponibles .

Escribí un artículo sobre los conceptos básicos y las sutilezas de Unicode y Perl , debería darle una buena idea sobre qué hacer para que Perl reconozca su cadena como una secuencia de caracteres, no solo una secuencia de bytes.

Actualización: con Unicode no obtienes un comportamiento dependiente del idioma, sino que, por el contrario, los valores predeterminados sanos, independientemente del idioma. Esto puede o no ser lo que quieres, pero para la distinción de carácter imprimible / control no veo por qué necesitarías un comportamiento dependiente del idioma.

\ X coincide con un carácter (secuencia) completamente compuesto. Prueba:

#!/usr/bin/env perl
use 5.010;
use utf8;
use Encode qw(encode_utf8);

for my $string (qw(あ ご ご), "\x{3099}") {
    say encode_utf8 sprintf "%s $string", $string =~ /\A \X \z/msx ? 'ok' : 'nok';
}

Los datos de prueba son: un carácter normal, un carácter pre-combinado, una secuencia de caracteres de combinación y un carácter de combinación (que no cuenta por sí solo, una simplificación del Capítulo 3 de Unicode).

Sustituya \ X por [[: print:]] para ver que la respuesta de Tanktalus produce coincidencias falsas para los dos últimos casos.

Sí, esas expresiones dependen de la configuración regional.

Siempre se puede usar la clase de caracteres [^ [: cntrl:]] para hacer coincidir los caracteres que no son de control.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top