¿Cómo obtener caracteres con su valor Unicode?

¿Cómo obtener caracteres con su valor Unicode?

Tengo el carácter Unicode ᚠ, representado por su punto de código Unicode 16A0, en un archivo de texto (el archivo de texto está codificado (?) como utf-8).

Cuando lo hago grep '\u16A0' test.txtno obtengo ningún resultado. ¿Cómo puedo agarrar ese personaje?

Respuesta1

Puedes usarcotización ANSI-Cproporcionado por su shell, para reemplazar los caracteres de escape con barra invertida según lo especificado por el estándar ANSI C. Esto debería funcionar para cualquier comando, no solo grep, en shells como Bash y Zsh:

grep $'\u16A0'

Para ver algunos ejemplos más complejos, puede consultaresta pregunta relacionaday sus respuestas.

Respuesta2

Podrías usarugrepcomo reemplazo directo de grep para que coincida con el punto de código Unicode U+16A0:

ugrep '\x{16A0}' test.txt

Toma las mismas opciones que grep pero ofrece muchas más funciones, como:

ugrep busca entradas UTF-8/16/32 y otros formatos. La opción -Q permite buscar muchos otros formatos de archivos, como ISO-8859-1 a 16, EBCDIC, páginas de códigos 437, 850, 858, 1250 a 1258, MacRoman y KIO8.

ugrep coincide con patrones Unicodede forma predeterminada (deshabilitado con la opción -U). La sintaxis del patrón de expresión regular es compatible con POSIX ERE ampliada con una sintaxis similar a PCRE. La opción -P también se puede utilizar para hacer coincidir Perl con patrones Unicode.

Verugrep en GitHubpara detalles.

Respuesta3

Usandorakú(anteriormente conocido como Perl_6)

Entrada de muestra:

https://www.cogsci.ed.ac.uk/~richard/unicode-sample-3-2.html


Haga coincidir el carácter, imprima la línea:

~$ raku -ne '.put if m/ \x[16A0] /;'  file
ᚠ ᚡ ᚢ ᚣ ᚤ ᚥ ᚦ ᚧ ᚨ ᚩ ᚪ ᚫ ᚬ ᚭ ᚮ ᚯ ᚰ ᚱ ᚲ ᚳ ᚴ ᚵ ᚶ ᚷ ᚸ ᚹ ᚺ ᚻ ᚼ ᚽ ᚾ ᚿ ᛀ ᛁ ᛂ ᛃ ᛄ ᛅ ᛆ ᛇ ᛈ ᛉ ᛊ ᛋ ᛌ ᛍ ᛎ ᛏ ᛐ ᛑ ᛒ ᛓ ᛔ ᛕ ᛖ ᛗ ᛘ ᛙ ᛚ ᛛ ᛜ ᛝ ᛞ ᛟ ᛠ ᛡ ᛢ ᛣ ᛤ ᛥ ᛦ ᛧ ᛨ ᛩ ᛪ ᛫ ᛬ ᛭ ᛮ ᛯ ᛰ

#OR:

~$ raku -e  'lines.grep(/ \x[16A0] /).put;'  file
ᚠ ᚡ ᚢ ᚣ ᚤ ᚥ ᚦ ᚧ ᚨ ᚩ ᚪ ᚫ ᚬ ᚭ ᚮ ᚯ ᚰ ᚱ ᚲ ᚳ ᚴ ᚵ ᚶ ᚷ ᚸ ᚹ ᚺ ᚻ ᚼ ᚽ ᚾ ᚿ ᛀ ᛁ ᛂ ᛃ ᛄ ᛅ ᛆ ᛇ ᛈ ᛉ ᛊ ᛋ ᛌ ᛍ ᛎ ᛏ ᛐ ᛑ ᛒ ᛓ ᛔ ᛕ ᛖ ᛗ ᛘ ᛙ ᛚ ᛛ ᛜ ᛝ ᛞ ᛟ ᛠ ᛡ ᛢ ᛣ ᛤ ᛥ ᛦ ᛧ ᛨ ᛩ ᛪ ᛫ ᛬ ᛭ ᛮ ᛯ ᛰ

Haga coincidir el carácter, imprima la "palabra" (separada por espacios en blanco):

~$ raku -ne 'for .words() { .put if m/ \x[16A0] / };'  file

#OR:

~$ raku -e  'words.grep(/ \x[16A0] /).put;'  file

Haga coincidir el carácter, imprima las coincidencias (exactas):

~$ raku -e 'given slurp() { put m:g/  \x[16A0]  / };'   file

#OR:

~$ raku -e 'slurp.match(:global,/  \x[16A0]  /).put;'   file

Haga coincidir el personaje, cuente las coincidencias e imprima:

~$ raku -e 'given slurp() { put m:g/  \x[16A0]  /.Int };'   file
1

#OR:

~$ raku -e 'slurp.match(:global,/  \x[16A0]  /).elems.put;'   file
1 

NOTAS:

  1. En Raku puedes comparar fácilmente con un nombre Unicode como \c[RUNIC LETTER FEHU FEOH FE F], lo que da los mismos resultados que la comparación \x[16A0]anterior.

  2. En Raku puedes comparar fácilmente con un carácter Unicode como , lo que da los mismos resultados que comparar con \x[16A0]o \c[RUNIC LETTER FEHU FEOH FE F]superior.

  3. En Raku, puedes usar variables Unicode (así como operadores Unicode). Entonces esto funciona:

~$ raku -e 'my $ᚠ = slurp.match(/  \x[16A0]  /); say $ᚠ.Str.raku;'   file
"ᚠ"

https://docs.raku.org/language/regexes#Unicode_properties
https://docs.raku.org/language/unicode
https://docs.raku.org
https://raku.org

Respuesta4

Con perl, pcre2grepo pcregrepcualquier grepimplementación que use o pueda usar PCRE o PCRE2 al menos, puede usarlo \x{16A0}para hacer coincidir el carácter con valor 0x16A0(o solo \xe9para valores <= 0xff).

Para que ese valor sea el punto de código Unicode, debemos decirles que la entrada debe decodificarse en UTF-8. En PCRE/PCRE2, eso es usando (*UTF)al inicio del patrón (principalmente equivalente a pasar PCRE_UTFal motor de expresiones regulares), aunque las versiones recientes de GNU grepal menos lo hacen automáticamente cuando se invoca en una configuración regional que usa UTF-8 como su mapa de encanto. Con pcregrepy pcre2grep, eso también se puede habilitar con la -uopción (ver también -Uen pcre2grep).

En perl, eso es a través de la -Copción (gran carácter) de la PERL_UNICODEvariable de entorno. Donde -Csolo, abreviatura -CSDLes decodificar/recodificar recodificar entrada/salida como UTF-8 si la configuración regional usa UTF-8 como greplo hace GNU, o -CSDhacerlo incondicionalmente, o decodificar explícitamente desde cualquier codificación usando, por ejemplo, el Encodemódulo.

En perly PCRE2 (como se usa en pcre2greplas versiones recientes de GNU grep), también puedes usar \N{U+16A0}. Y en perlsu nombre Unicode: \N{RUNIC LETTER FEHU FEOH FE F}.

Entonces:

perl -C -ne 'print if /\x{16A0}/'
perl -C -ne 'print if /\N{U+16A0}/'
perl -C -ne 'print if /\N{RUNIC LETTER FEHU FEOH FE F}/'
PERL_UNICODE=SD perl -ne 'print if /\x{16A0}/'
pcregrep -u '\x{16A0}'
pcregrep '(*UTF)\x{16A0}'
pcre2grep -u '\x{16A0}'
pcre2grep '(*UTF)\x{16A0}'
pcre2grep -U '\x{16A0}'
pcre2grep -u '\N{U+16A0}'
grep -P '\x{16A0}'

Para hacer coincidir un carácter según su valor Unicode en una entrada que no está codificada en UTF-8, no funcionará porque solo funciona en UTF-8. En conjuntos de caracteres de un solo byte, \xHHfuncionará con el valor por (el punto de código en el conjunto de caracteres correspondiente, no en Unicode).

Por ejemplo, en la en_GB.iso885915configuración regional, donde el signo del euro (U+20AC) está en 0xA4.

$ LC_ALL=en_GB.iso885915 luit
$ locale charmap
ISO-8859-15
$ printf %s € | od -An -vtx1
 a4
$ echo € | grep -P '\x{20ac}'
grep: character code point value in \x{} or \o{} is too large
$ echo € | grep -P '\N{U+20ac}'
grep: \N{U+dddd} is supported only in Unicode (UTF) mode
$ echo € | grep -P '(*UTF)\N{U+20ac}'
$ echo € | grep -P '\xA4'

Entonces las opciones serían convertir el texto a UTF-8:

$ echo € | iconv -t utf-8 | LC_ALL=C.UTF-8 grep -P '\x{20ac}' | iconv -f utf-8

O si usa perluse -Mopen=localeen lugar de -Cdecirle que decodifique/codifique la entrada/salida según el conjunto de caracteres de la configuración regional en lugar de UTF-8:

$ echo € | perl -Mopen=locale -ne 'print if /\N{U+20ac}/'

O no realizar ninguna decodificación, pero hacer coincidir el valor de byte de ese carácter en la configuración regional.

Por ejemplo, con GNU o zsh o versiones recientes de bash printf:

$ locale charmap
ISO-8859-15
$ printf '\u20ac' | od -An -vtx1
 a4
$ echo € | grep -F -- "$(printf '\u20ac')"

En zsh, también puede usar $'\u20ac'which se expandirá a la codificación del carácter en la configuración regional actual en ese momento (e informará un error si no existe dicho carácter en esa configuración regional).

$ echo € | grep -F -- $'\u20ac'

Varios otros shells han copiado eso $'\uHHHH'de zsh desde que incluyeron ksh93, bash, mksh y algunos shells basados ​​en ash, pero con algunas diferencias desafortunadas: en ksh, se expandió en UTF-8 independientemente de la configuración regional, y con bash, se expandió en el configuración regional en el momento en que se lee el código en lugar de en el momento en que se ejecuta el código, por ejemplo, en bash:

LC_CTYPE=C.UTF-8
{
  LC_CTYPE=en_GB.iso885915
  printf '\xA4\n' | grep -F -- $'\u20ac'
}

O:

LC_CTYPE=C.UTF-8
euro() {
  grep -F -- $'\u20ac'
}
LC_CTYPE=en_GB.iso885915
printf '\xa4\n' | euro

No funcionará porque en ambos casos, $'\u20ac'se expande a su codificación UTF-8 ya que LC_CTYPE=en_GB.iso885915no se había ejecutado cuando $'\u20ac'el shell lo analizó.

información relacionada