regex - tester - ¿Cómo comparo solo caracteres completamente compilados en una cadena Unicode en Perl?
perl regex tester (5)
Estoy buscando una manera de hacer coincidir solo caracteres completamente compuestos en una cadena Unicode.
¿ [:print:]
depende de la configuración regional en cualquier implementación de expresiones regulares 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 códigos ASCII 0x20 a 0x7E?
¿Hay alguna clase de caracteres, incluidos Perl RE, que se pueda usar para hacer coincidir algo que no sea un personaje de control? Si [:print:]
incluye solo caracteres en el rango ASCII, asumiría que [:cntrl:]
también lo hace.
Creo que no quieres o necesitas configuraciones regionales para eso, sino más bien Unicode. Si ha decodificado una cadena de texto, /w
coincidirá con los caracteres de las palabras en cualquier idioma, /d
coincide no solo con 0..9
sino con cada dígito Unicode, etc. En las expresiones regulares, puede consultar las propiedades Unicode con /p{PropertyName}
. Particularmente interesante para usted podría ser /p{Print}
. 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 que perl reconocerá su cadena como una secuencia de caracteres, no solo una secuencia de bytes.
Actualización: con Unicode no se obtiene un comportamiento dependiente del idioma, sino valores predeterminados sanos independientemente del idioma. Esto puede o no ser lo que quieres, pero para la distinción de carácter priintable / control no veo por qué necesitarías un comportamiento que dependa del idioma.
Sí, esas expresiones dependen de la configuración regional.
Siempre puede usar la clase de caracteres [^[:cntrl:]]
para [^[:cntrl:]]
los caracteres que no son de control.
/X
coincide con un carácter completamente compuesto (secuencia). 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 precombinado, una secuencia de caracteres combinada y un carácter de combinación (que "no cuenta" por sí mismo, una simplificación del Capítulo 3 de Unicode).
Sustituya /X
con [[:print:]]
para ver que la respuesta de Tanktalus produce coincidencias falsas para los dos últimos casos.
echo あ| perl -nle ''BEGIN{binmode STDIN,":utf8"} print"[$_]"; print /[[:print:]]/ ? "YES" : "NO"''
Esto funciona principalmente, aunque genera una advertencia sobre un personaje ancho. Pero te da la idea: debes estar seguro de que estás tratando con una cadena Unicode real (comprueba utf8 :: is_utf8). O simplemente revisa el perlunicodo : todo el tema aún me da vueltas la cabeza.