Що в цих Unicode, що поєднують символи, і як ми можемо їх відфільтрувати?


91

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

Вони нещодавно з’явились у розділах коментарів на Facebook.

Як ми можемо продезінфікувати це?


5
Ви раніше не задавали цього питання? (Чесне запитання.)
Ry-

5
Це точно не ascii
Кріс Еберле

31
Чому підсумкові голосування? Це питання, пов’язане з програмуванням, оскільки я хочу знати, як дезінфікувати цей тип введення, тому розділи коментарів на моєму веб-сайті не будуть майданчиком для 13-річного віку ...
XCS,

17
So ก้้้้้้้้้้้้้้้้้้้้ ก็็็็็็็็็็็็็็็็็็็็ ก็็็็็็็็็็็็็็็็็็็็ กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้ ก็็็็็็็็็็็็็็็็็็็็ กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้ กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้ ก็็็็็็็็็็็็็็็็็็็็ ก็็็็็็็็็็็็็็็็็็็็ กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้ ก็็็็็็็็็็็็็็็็็็็็ กิิิิิิิิิิิิิิิ ", тому розділи коментарів на моєму веб-сайті не будуть ігровим майданчиком 13 років". Насправді без санітарної обробки один публікуючи ці символи може зробити коментар над ним нечитабельним, що зовсім не є приємним користувальницьким досвідом.
XCS

14
@pjotr Це точно не помилка браузера. Якщо ви хочете, щоб символи не переповнювали вміщуване поле, ви можете просто вирішити це за допомогою CSS (overflow: hidden;) ...
XCS

Відповіді:


80

Що з цими символами Unicode?

Це персонаж із низкою поєднання символів . Оскільки об'єднані символи, про які йдеться, хочуть перевищувати базовий символ, вони складаються (буквально). Наприклад, справа

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

... це ก (тайський символ ko kai ) ( U + 0E01 ), за яким слідують 20 копій тайського поєднуючого символу mai tho ( U + 0E49 ).

Як ми можемо продезінфікувати це?

Ви можете попередньо обробити текст і обмежити кількість поєднаних символів, які можна застосувати до одного символу, але зусилля можуть не вартувати винагороди. Вам знадобляться аркуші даних для всіх поточних символів, щоб ви знали, чи вони поєднуються, чи що, і вам потрібно бути впевненим, що дозволили хоча б кілька, оскільки деякі мови написані з кількома діакритичними знаками на одній основі . Тепер, якщо ви хочете обмежити коментарі латинським набором символів, це було б простіше перевірити діапазон, але, звичайно, це лише варіант, якщо ви хочете обмежити коментарі лише кількома мовами. Більше інформації, таблиць кодів тощо на сайті unicode.org .

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


1
Чи не просто б ви видалити повторювані копії того самого комбінуючого кодового пункту назад до назад в одну копію? Коли вам коли-небудь потрібно буде поєднувати одну і ту ж кодову точку з базовою кодовою точкою більше одного разу?
Ремі Лебо,

4
@RemyLebeau: "Коли вам коли-небудь потрібно буде поєднувати одну і ту ж кодову точку з базовою кодовою точкою більше одного разу?" Я не знаю, я знаю дуже, дуже мало про те, як ви пишете інші мови - тайську, наприклад. Я б зовсім не був здивований, коли дізнався, що в одних з них діяло більше одного і того ж кодового пункту. Але це не зменшує складності; вам все ще потрібна одна з таблиць Unicode, щоб з’ясувати, які з них поєднують символи.
TJ Crowder,

Я змусив вашу сторінку прийняти рядок унікоду з URL-адреси, наприклад, jsbin.com/erajer/7/…
ubershmekel

2
Бібліотека JavaScript для легкого видалення знаків Unicode, що поєднують зі рядків: mths.be/stripcombiningmarks
Mathias Bynens

JavaScript використовує UTF-16 з « сурогатними парами »
долмен

17

Якщо у вас є механізм регулярних виразів з пристойною підтримкою 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");

Буде надруковано:

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


9
Я не вмію читати тибетський, але я стурбований тим, що цей грубий підхід може усунути функціональність із дизайну мови. Я бачив Юнікод, який має законні випадки використання більше, ніж одного комбінуючого знака. Хорошим прикладом є арабська. Я спробую не забути про це керувати своїми тибетськими колегами.
FlipMcF

2
Ви маєте рацію, є, звичайно, випадки, коли множинні знаки поєднання є законними. Але ви можете легко змінити регулярний вираз, щоб дозволити певний максимум позначок.
nwellnhof

Проголосував за те, що відповідає на запитання "як ви дезінфікуєте це"? Але я думаю, що це було б кошмаром для обслуговування.
FlipMcF

Крім того, RE просто видаляє сусіднє дублювання. Це не буде прибирати, скажімо: <base><macron><overline><macron><overline>.... Отже, якщо ваш текст потребує кількох різних символів, що поєднуються, він буде проходити добре; і шкідливий текст все ще міг бути створений.
Jesse Chisholm

13

"Як ми можемо це продемонструвати", найкраще відповідає вище TJ Crowder

Однак я думаю, що санітарія - це неправильний підхід, і Крісті це правильно з overflow:hiddenелементом, що містить css.

Принаймні, я так це вирішую.


6

Гаразд, це зайняло у мене деякий час, щоб зрозуміти, у мене склалося враження, що поєднання символів для створення залго обмежується цими . Тож я очікував, що після регулярного виразу піймаю виродків.

([\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.

ОНОВЛЕННЯ:

Ось оновлений регулярний вираз, який повинен виловлювати всі залго, включаючи ті, які обійшли в "нормальному" діапазоні.

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

Найскладніше - ідентифікувати їх, як тільки ви це зробите - є безліч рішень, включаючи декілька хороших вище.

Сподіваюся, це заощадить ваш час.


Я б сказав, щоб не спамувати цей спам!
Правен Кумар Пурушотаман

@PraveenKumar Чи хотіли б Ви детальніше розказати, що Ви маєте на увазі?
Матас Вайткевічус,

Я вдячний вашій відповіді, але це втрачене запитання. То навіщо додавати нові відповіді без потреби? Це лише мій погляд. Більше того, ваша відповідь - це не JavaScript, правда?
Правен Кумар Пурушотаман

4
@PraveenKumar Розкриває, чому звичайна перевірка zalgo ([\u0300–\u036F\u1AB0–\u1AFF\u1DC0–\u1DFF\u20D0–\u20FF\uFE20–\uFE2F]{2,})не працює. Вам не цікаво, що укладання Unicode не обмежується лише тим, що на wiki? Що ви маєте на увазі під словом "загублене запитання"? РЕДАГУВАТИ : Можливо, вам буде дивним додати відповідь на трирічне запитання, але оскільки мені знадобився час, щоб зрозуміти, чому цей тип залго працював, я не міг дозволити таким знанням піти даремно. Наступний хлопець заощадить трохи часу.
Матас Вайткевічус,

7
@PraveenKumar у питанні не вказано мови, а розміщення нової відповіді на старе питання цілком доречно, якщо старі відповіді якимось чином були дефіцитними. На жаль, у мене недостатньо досвіду з цією проблемою, інакше вона отримала б голос за мене.
Марк Ренсом,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.