in

Diferencia entre NFD, NFC, NFKD y NFKC explicada con código Python

10BDFnrW J2zDIL4 GpzE6g

Diferencia entre NFD, NFC, NFKD y NFKC explicada con código Python

La diferencia entre las formas de normalización Unicode

Xu LIANG

14 de nov. De 2019·4 min de lectura

1*0BDFnrW J2zDIL4 GpzE6g

Recientemente estoy trabajando en una tarea de PNL en japonés, un problema es convertir caracteres especiales a una forma normalizada. Así que investigué un poco y escribí esta publicación para cualquiera que tenga la misma necesidad.

El japonés contiene diferentes formas del carácter, por ejemplo, el latín tiene dos formas, forma de ancho completo y medio ancho.

En el ejemplo anterior, podemos ver que el formulario de ancho completo es muy feo y también es difícil de utilizar para el siguiente procesamiento. Entonces necesitamos convertirlo a una forma normalizada.

TL; DR

Usar NFKC método.

>>> from unicodedata import normalize
>>> s = "株式会社KADOKAWA Future Publishing"
>>> normalize('NFKC', s)
株式会社KADOKAWA Future Publishing

Formas de normalización Unicode

1* irZeGalg3lwm2pQoHtUFw

Haymi 4 tipos de formularios de normalización Unicode. Este artículo da una explicación muy detallada. Pero explicaré la diferencia de una manera simple y fácil de entender.

Primero, pudimos ver el siguiente resultado para una comprensión intuitiva.

アイウエオ ==(NFC)==> アイウエオ
アイウエオ ==(NFD)==> アイウエオ
アイウエオ ==(NFKC)==> アイウエオ
アイウエオ ==(NFKD)==> アイウエオ
パピプペポ ==(NFC)==> パピプペポ
パピプペポ ==(NFD)==> パピプペポ
パピプペポ ==(NFKC)==> パピプペポ
パピプペポ ==(NFKD)==> パピプペポ
パピプペポ ==(NFC)==> パピプペポ
パピプペポ ==(NFD)==> パピプペポ
パピプペポ ==(NFKC)==> パピプペポ
パピプペポ ==(NFKD)==> パピプペポ
abcABC ==(NFC)==> abcABC
abcABC ==(NFD)==> abcABC
abcABC ==(NFKC)==> abcABC
abcABC ==(NFKD)==> abcABC
123 ==(NFC)==> 123
123 ==(NFD)==> 123
123 ==(NFKC)==> 123
123 ==(NFKD)==> 123
+-.~)} ==(NFC)==> +-.~)}
+-.~)} ==(NFD)==> +-.~)}
+-.~)} ==(NFKC)==> +-.~)}
+-.~)} ==(NFKD)==> +-.~)}

Hay dos métodos de clasificación para estas 4 formas.

# 1 original form changed or not
- A(not changed): NFC & NFD
- B(changed): NFKC & NFKD
# 2 the length of original length changed or not
- A(not changed): NFC & NFKC
- B(changed): NFD & NFKD

1 Si se cambia o no la forma original

abcABC ==(NFC)==> abcABC
abcABC ==(NFD)==> abcABC
abcABC ==(NFKC)==> abcABC
abcABC ==(NFKD)==> abcABC
# 1 original form changed or not
- A(not changed): NFC & NFD
- B(changed): NFKC & NFKD

El primer método de clasificación se basa en si se cambia o no la forma original. Más específicamente, un grupo no contiene K pero el grupo B contiene K. Que hace K ¿medio?

D = Decomposition 
C = Composition
K = Compatibility

K significa compatibilidad, que se utiliza para distinguir con la forma original. Porque K cambia la forma original, por lo que también se cambia la longitud.

>>> s= '…'
>>> normalize('NFKC', s)
'...'
>>> len(s)
1
>>> len(normalize('NFC', s))
1
>>> len(normalize('NFKC', s))
3
>>> len(normalize('NFD', s))
1
>>> len(normalize('NFKD', s))
3

2 Si se cambia o no la longitud del formulario original

パピプペポ ==(NFC)==> パピプペポ
パピプペポ ==(NFD)==> パピプペポ
パピプペポ ==(NFKC)==> パピプペポ
パピプペポ ==(NFKD)==> パピプペポ
# 2 the length of original length changed or not
- A(not changed): NFC & NFKC
- B(changed): NFD & NFKD

Este segundo método de clasificación se basa en si se cambia o no la longitud del formulario original. Un grupo contiene C(Composición), que no cambiará la longitud. El grupo B contiene D(Descomposición), que cambiará la longitud.

Quizás se pregunte por qué se cambia la longitud. Consulte la prueba a continuación.

>>> from unicodedata import normalize
>>> s = "パピプペポ"
>>> len(s)
5
>>> len(normalize('NFC', s))
5
>>> len(normalize('NFKC', s))
5
>>> len(normalize('NFD', s))
10
>>> len(normalize('NFKD', s))
10

Podemos encontrar que el método de «descomposición» duplica la longitud.

Esto se debe a que NFD & NFKD descomponga cada carácter Unicode en dos caracteres Unicode. Por ejemplo, ポ(U+30DD) = ホ(U+30DB) + Dot(U+309A) . Entonces la longitud cambia de 5 a 10. NFC & NFKC componga caracteres Unicode separados juntos, por lo que la longitud no se modifica.

Implementación de Python

Puede utilizar la biblioteca unicodedata para obtener diferentes formularios.

>>> from unicodedata import normalize
>>> s = "パピプペポ"
>>> len(s)
5
>>> len(normalize('NFC', s))
5
>>> len(normalize('NFKC', s))
5
>>> len(normalize('NFD', s))
10
>>> len(normalize('NFKD', s))
10

Largo

Quitar

Por lo general, podemos usar cualquiera de NFKC or NFKD para obtener la forma normalizada. La longitud no causará problemas solo si su tarea de PNL es sensible a la longitud. Yo suelo usar el NFKC método.

Mira mis otras publicaciones en Medio con una vista categorizada!
GitHub:
BrambleXu
LinkedIn:
Xu Liang
Blog:
BrambleXu

Referencia

  • https://unicode.org/reports/tr15/#Norm_Forms
  • https://www.wikiwand.com/en/Unicode_equivalence#/Normal_forms
  • http://nomenclator.la.coocan.jp/unicode/normalization.htm
  • https://maku77.github.io/js/string/normalize.html
  • http://tech.albert2005.co.jp/501/

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

uber ubicacion traslados 12805

Cómo actualizar y cambiar mi número de teléfono y mi dirección de correo electrónico en la aplicación Uber

oracleClusterware