unicode sanitize combining-marks zalgo

¿Qué pasa con estos caracteres de combinación Unicode y cómo podemos filtrarlos?



sanitize combining-marks (4)

¿Qué pasa con estos personajes Unicode?

Es un personaje con una serie de personajes combinados . Debido a que los personajes combinados en cuestión quieren ir por encima del personaje base, se acumulan (literalmente). Por ejemplo, el caso de

ก้้้้้้้้้้้้้้้้้้้้

... es un ก (carácter tailandés ko kai ) ( U+0E01 ) seguido de 20 copias del carácter combinado tailandés mai tho ( U+0E49 ).

¿Cómo podemos sanitizar esto?

Puede preprocesar el texto y limitar el número de caracteres combinados que se pueden aplicar a un solo personaje, pero puede que el esfuerzo no valga la pena. Necesitarías las hojas de datos para todos los personajes actuales para saber si estaban combinando o qué, y necesitarías asegurarte de permitir al menos unos pocos porque algunos idiomas están escritos con varios signos diacríticos en una sola base. . Ahora, si desea limitar los comentarios al conjunto de caracteres latinos, sería una verificación de rango más fácil, pero, por supuesto, esa es solo una opción si desea limitar los comentarios a solo algunos idiomas. Más información, hojas de códigos, etc. en unicode.org .

Por cierto, si alguna vez quieres saber cómo se compuso un personaje, recientemente te codifiqué una página rápida y sucia de "Mostrar Unicode" en JSBin. Simplemente copie y pegue el texto en el área de texto, y le mostrará todos los puntos de código (~ caracteres) que componen el texto, con enlaces como los de arriba a la página que describe cada personaje. Solo funciona para puntos de código en el rango U + FFFF y menos, porque está escrito en JavaScript y para manejar caracteres superiores a U + FFFF en JavaScript, debe hacer más trabajo del que yo quería hacer para esa pregunta (porque en JavaScript, un "personaje" siempre es de 16 bits, lo que significa que para algunos idiomas un personaje se puede dividir entre dos "caracteres" de JavaScript separados y no tuve en cuenta eso), pero es útil para la mayoría de los textos ...

กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้ ก็็็็็็็็็็็็็็็็็็็็ ก็็็็็็็็็็็็็็็็็็็็ กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้ ก็็็็็็็็็็็็็็็็็็็็ กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้ กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้ ก็็็็็็็็็็็็็็็็็็็็ ก็็็็็็็็็็็็็็็็็็็็ กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้ ก็็็็็็็็็็็็ ็็็็็็็ กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้

Estos recientemente aparecieron en las secciones de comentarios de Facebook.

¿Cómo podemos sanitizar esto?


"¿Cómo podemos sanitizar esto?" Es mejor respondida anteriormente por

Sin embargo, creo que la sanitización es un enfoque equivocado, y tiene razón con el overflow:hidden en el elemento que contiene CSS.

Al menos, así es como lo estoy resolviendo.


Ok, este me tomó un tiempo para descifrar, estaba bajo la impresión de que la combinación de caracteres para producir zalgo se limita a estos . Así que esperaba seguir a Regex para atrapar a los monstruos.

([/u0300–/u036F/u1AB0–/u1AFF/u1DC0–/u1DFF/u20D0–/u20FF/uFE20–/uFE2F]{2,})

y no funcionó ...

El problema es que esa lista en wiki no cubre la gama completa de caracteres combinados.

Lo que me dio una pista es "ก้้้้้้้้้้้้้้้้้้้้".charCodeAt(2).toString(16) = "e49" que dentro de un rango de combinación, cae en "Uso privado".

En C # caen bajo UnicodeCategory.NonSpacingMark y el siguiente script los UnicodeCategory.NonSpacingMark :

[Test] public void IsZalgo() { var zalgo = new[] { UnicodeCategory.NonSpacingMark }; File.Delete("IsModifyLike.html"); File.AppendAllText("IsModifyLike.html", "<table>"); for (var i = 0; i < 65535; i++) { var c = (char)i; if (zalgo.Contains(Char.GetUnicodeCategory(c))) { File.AppendAllText("IsModifyLike.html", string.Format("<tr><td>{0}</td><td>{1}</td><td>{2}</td><td>A&#{3};&#{3};&#{3}</td></tr>/n", i.ToString("X"), c, Char.GetUnicodeCategory(c), i)); } } File.AppendAllText("IsModifyLike.html", "</table>"); }

Al mirar la tabla generada, debería poder ver cuáles se acumulan. Un rango que falta en el wiki es 06D6-06DC otro 0730-0749 .

ACTUALIZAR:

Aquí está la expresión regular actualizada que debe pescar todos los zalgo, incluidos los omitidos en el rango "normal".

([/u0300–/u036F/u1AB0–/u1AFF/u1DC0–/u1DFF/u20D0–/u20FF/uFE20–/uFE2F/u0483-/u0486/u05C7/u0610-/u061A/u0656-/u065F/u0670/u06D6-/u06ED/u0711/u0730-/u073F/u0743-/u074A/u0F18-/u0F19/u0F35/u0F37/u0F72-/u0F73/u0F7A-/u0F81/u0F84/u0e00-/u0eff/uFC5E-/uFC62]{2,})

Lo más difícil es identificarlos, una vez que hayas hecho eso, hay una gran cantidad de soluciones, incluidas algunas buenas arriba.

Espero que esto te ahorre algo de tiempo.


Si tiene un motor regex con un soporte decente de Unicode, es trivial desinfectar este tipo de cadenas. En Perl, por ejemplo, puede eliminar todas las marcas de combinación, excepto la primera, de todos los caracteres (percibidos por el usuario) como este:

#!/usr/bin/perl use strict; use utf8; binmode(STDOUT, '':utf8''); my $string = "กิิ ก้้ ก็็ ก็็ กิิ ก้้ ก็็ กิิ ก้้ กิิ ก้้ ก็็ ก็็ กิิ ก้้ ก็็ กิิ ก้้"; $string =~ s/(/p{Mark})/p{Mark}+/$1/g; # Strip excess combining marks print("$string/n");

Esto se imprimirá:

กิ ก้ ก้ ก็ ก็ ก็ ก้ ก้ ก้ ก้ ก้ ก้ ก้ ก้