Что с этим Unicode объединяет символы и как мы можем их фильтровать?

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

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

Как мы можем это сделать?

Ответ 1

Что происходит с этими символами Unicode?

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

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

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

Как мы можем это сделать?

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

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

Ответ 2

Если у вас есть механизм регулярных выражений с приличной поддержкой 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");

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

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

Ответ 3

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

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

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

Ответ 4

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

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

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

Уловка состоит в том, что этот список в вики не охватывает весь диапазон комбинаций символов.

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

В С# они попадают под 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 отсутствующий в wiki, - 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,})

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

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