Что случилось с этими Unicode-символами и как мы можем их отфильтровать?

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

Они недавно появились в разделах комментариев на Facebook.

Как мы можем продезинфицировать это?

4 ответа

Решение

Что случилось с этими символами Юникода?

Это персонаж с серией комбинированных персонажей. Поскольку рассматриваемые символы объединения хотят идти выше базового символа, они складываются (буквально). Например, случай

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

... это ก (тайский символ ko kai) ( U + 0E01), за которым следуют 20 копий тайского комбинирующего символа mai tho ( U + 0E49).

Как мы можем продезинфицировать это?

Вы можете предварительно обработать текст и ограничить количество комбинируемых символов, которые могут быть применены к одному символу, но эти усилия могут не стоить награды. Вам понадобятся таблицы данных для всех текущих символов, чтобы вы знали, объединяются ли они или что-то еще, и вы должны обязательно разрешить хотя бы несколько, потому что некоторые языки написаны с несколькими диакритическими знаками на одной основе., Теперь, если вы хотите ограничить комментарии набором латинских символов, это будет более простой проверкой диапазона, но, конечно, это вариант, если вы хотите ограничить комментарии только несколькими языками. Больше информации, кодовых листов и т. Д. На http://unicode.org/.

Кстати, если вы когда-нибудь захотите узнать, как был составлен какой-то персонаж, то для другого вопроса я недавно написал кодовую страницу "Unicode Show Me" на JSBin. Вы просто копируете и вставляете текст в текстовую область, и он показывает все кодовые точки (~ символы), из которых состоит текст, со ссылками, подобными приведенным выше, на страницу, описывающую каждый символ. Он работает только для кодовых точек в диапазоне U+FFFF и ниже, потому что он написан на JavaScript, и для обработки символов выше U+FFFF в JavaScript вы должны выполнить больше работы, чем я хотел сделать для этого вопроса (потому что в JavaScript "характер" всегда 16 бит, что означает, что для некоторых языков символ можно разделить на два отдельных "символа" JavaScript, и я не учел это), но это удобно для большинства текстов...

Если у вас есть движок регулярных выражений с приличной поддержкой Unicode, очистить этот тип строк тривиально. Например, в Perl вы можете удалить все, кроме первой метки объединения, с каждого (воспринимаемого пользователем) символа следующим образом:

#!/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");

Это напечатает:

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

"Как мы можем продезинфицировать это", лучше всего ответил выше T.J. Crowder

Тем не менее, я думаю, что санитария это неправильный подход, и Cristy правильно overflow:hidden на элементе, содержащем CSS.

По крайней мере, так я это решаю.

Хорошо, это заняло у меня некоторое время, чтобы понять, у меня сложилось впечатление, что объединение персонажей для создания залго ограничено этим. Поэтому я ожидал, что после регулярного выражения поймать уродов.

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

и это не сработало...

Загвоздка в том, что список в вики не охватывает весь спектр комбинируемых символов.

Что подсказало мне "ก้้้้้้้้้้้้้้้้้้้้".charCodeAt(2).toString(16) = "e49", который не входит в диапазон объединения, он попадает в "Частное использование".

В C# они подпадают под 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>");
    }

Глядя на сгенерированную таблицу, вы сможете увидеть, какие из них складываются. Один диапазон, который отсутствует в вики это 06D6-06DC другой 0730-0749,

ОБНОВИТЬ:

Вот обновленное регулярное выражение, которое должно вылавливать все zalgo, включая те, которые обойдены в "нормальном" диапазоне.

([\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,})

Самое сложное - это определить их, как только вы это сделаете - есть множество решений, в том числе и некоторые из приведенных выше.

Надеюсь, это сэкономит вам время.

Другие вопросы по тегам