Ada apa dengan karakter gabungan Unicode ini dan bagaimana kita dapat memfilternya?

91

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

Ini baru-baru ini muncul di bagian komentar facebook.

Bagaimana kita bisa membersihkan ini?

XCS
sumber
5
Pernahkah Anda menanyakan pertanyaan ini sebelumnya? (Pertanyaan yang jujur.)
Ry-
5
Itu pasti tidak ascii
Chris Eberle
31
Mengapa pemungutan suara penutup? Ini adalah pertanyaan yang berhubungan dengan pemrograman, karena saya ingin tahu cara membersihkan jenis input ini sehingga bagian komentar di situs saya tidak akan menjadi taman bermain anak berusia 13 tahun ...
XCS
17
กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้ ก็็็็็็็็็็็็็็็็็็็็ ก็็็็็็็็็็็็็็็็็็็็ กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้ ก็็็็็็็็็็็็็็็็็็็็ กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้ กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้ ก็็็็็็็็็็็็็็็็็็็็ ก็็็็็็็็็็็็็็็็็็็็ กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้ ก็็็็็็็็็็็็็็็็็็็็ กิิิิิิิิิิิิิิิ "jadi bagian komentar di situs web saya tidak akan menjadi tempat bermain anak berusia 13 tahun." Sebenarnya tanpa sanitasi, satu posting karakter ini dapat membuat komentar di atasnya tidak dapat dibaca, yang sama sekali bukan pengalaman pengguna yang menyenangkan.
XCS
14
@pjotr Ini jelas bukan bug browser. Jika Anda ingin karakter tidak membanjiri kotak berisi, Anda dapat menyelesaikannya dengan CSS (overflow: hidden;) ...
XCS

Jawaban:

80

Ada apa dengan karakter unicode ini?

Itu adalah karakter dengan serangkaian karakter gabungan . Karena karakter penggabung yang dimaksud ingin melebihi karakter dasar, karakter tersebut bertumpuk (secara harfiah). Misalnya, kasus

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

... itu adalah ก (karakter Thai ko kai ) ( U + 0E01 ) diikuti oleh 20 salinan karakter gabungan Thai mai tho ( U + 0E49 ).

Bagaimana kita bisa membersihkan ini?

Anda dapat memproses teks sebelumnya dan membatasi jumlah karakter gabungan yang dapat diterapkan ke satu karakter, tetapi upaya tersebut mungkin tidak sepadan dengan hasilnya. Anda memerlukan lembar data untuk semua karakter saat ini sehingga Anda akan tahu apakah mereka bergabung atau apa, dan Anda harus memastikan untuk mengizinkan setidaknya beberapa karena beberapa bahasa ditulis dengan beberapa diakritik pada satu basis . Sekarang, jika Anda ingin membatasi komentar ke kumpulan karakter Latin, itu akan menjadi pemeriksaan rentang yang lebih mudah, tetapi tentu saja itu hanya opsi jika Anda ingin membatasi komentar hanya untuk beberapa bahasa. Informasi lebih lanjut, lembar kode, dll. Di unicode.org .

BTW, jika Anda ingin tahu bagaimana beberapa karakter disusun, untuk pertanyaan lain baru-baru ini saya membuat halaman "Unicode Show Me" yang cepat dan kotor di JSBin. Anda cukup menyalin dan menempel teks ke dalam area teks, dan ini menunjukkan kepada Anda semua titik kode (~ karakter) dari teks itu, dengan tautan seperti yang ada di atas ke halaman yang menjelaskan setiap karakter. Ini hanya berfungsi untuk poin kode dalam rentang U + FFFF dan di bawahnya, karena ditulis dalam JavaScript dan untuk menangani karakter di atas U + FFFF dalam JavaScript Anda harus melakukan lebih banyak pekerjaan daripada yang ingin saya lakukan untuk pertanyaan itu (karena dalam JavaScript, a "karakter" selalu 16 bit, yang berarti untuk beberapa bahasa karakter dapat dibagi menjadi dua "karakter" JavaScript yang terpisah dan saya tidak memperhitungkannya), tetapi berguna untuk sebagian besar teks ...

TJ Crowder
sumber
1
Tidakkah Anda hanya akan menghapus salinan berulang dari titik kode penggabungan yang sama kembali ke salinan tunggal? Kapan Anda perlu menggabungkan titik kode yang sama ke titik kode dasar lebih dari sekali?
Remy Lebeau
4
@RemyLebeau: "Kapan Anda perlu menggabungkan titik kode yang sama ke titik kode dasar lebih dari sekali?" Saya tidak tahu, saya tahu sangat, sangat sedikit tentang bagaimana Anda menulis bahasa lain - Thailand, misalnya. Saya tidak akan terkejut sama sekali saat mengetahui bahwa lebih dari satu titik kode yang sama valid di beberapa. Tetapi melakukan itu tidak mengurangi kerumitan; Anda masih memerlukan salah satu tabel Unicode untuk mengetahui tabel mana yang menggabungkan karakter.
TJ Crowder
Saya membuat halaman Anda menerima string unicode dari url misalnya jsbin.com/erajer/7/…
ubershmekel
2
Pustaka JavaScript untuk dengan mudah menghapus tanda gabungan Unicode dari string: mths.be/stripcombiningmarks
Mathias Bynens
JavaScript menggunakan UTF-16 dengan « pasangan pengganti »
dolmen
17

Jika Anda memiliki mesin regex dengan dukungan Unicode yang layak, sangat mudah untuk membersihkan string semacam ini. Di Perl, misalnya, Anda dapat menghapus semua kecuali tanda kombinasi pertama dari setiap karakter (yang dirasakan pengguna) seperti ini:

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

Ini akan mencetak:

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

nwellnhof
sumber
9
Saya tidak bisa membaca bahasa Tibet, tetapi saya khawatir bahwa pendekatan kekerasan ini dapat menghilangkan fungsionalitas dari cara desain bahasa tersebut. Saya telah melihat unicode yang memiliki kasus penggunaan yang sah dari lebih dari satu tanda gabungan. Bahasa Arab adalah contoh yang bagus. Saya akan mencoba mengingat untuk menjalankan ini oleh rekan kerja Tibet saya.
FlipMcF
2
Anda benar, pasti ada kasus di mana beberapa tanda penggabungan adalah sah. Tetapi Anda dapat dengan mudah mengubah ekspresi reguler untuk memungkinkan tanda maksimum tertentu.
nwellnhof
Suara positif karena itu menjawab pertanyaan 'bagaimana Anda membersihkan ini'. Tapi saya pikir ini akan menjadi mimpi buruk pemeliharaan.
FlipMcF
Selain itu, RE hanya menghapus duplikasi yang berdekatan . Itu tidak akan membersihkan, mengatakan: <base><macron><overline><macron><overline>.... Jadi, jika teks Anda membutuhkan beberapa karakter penggabungan yang berbeda , itu akan lolos dengan baik; dan teks berbahaya masih bisa dibuat.
Jesse Chisholm
13

"Bagaimana kita bisa membersihkan ini" adalah jawaban terbaik di atas oleh TJ Crowder

Namun, saya pikir sanitasi adalah pendekatan yang salah, dan Cristy melakukannya dengan benar overflow:hiddenpada elemen yang mengandung css.

Setidaknya, begitulah cara saya mengatasinya.

FlipMcF
sumber
6

Oke, yang ini butuh waktu lama untuk memikirkannya, saya mendapat kesan bahwa menggabungkan karakter untuk menghasilkan zalgo terbatas pada ini . Jadi saya berharap mengikuti regex untuk menangkap orang aneh.

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

dan itu tidak berhasil ...

Tangkapannya adalah bahwa daftar di wiki tidak mencakup seluruh kombinasi karakter.

Apa yang memberi saya petunjuk adalah "ก้้้้้้้้้้้้้้้้้้้้".charCodeAt(2).toString(16)= "e49" yang tidak berada dalam kisaran penggabungan, itu termasuk dalam 'Penggunaan pribadi'.

Di C # mereka berada di bawah UnicodeCategory.NonSpacingMarkdan skrip berikut menghapusnya:

    [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>");
    }

Dengan melihat tabel yang dihasilkan, Anda harus dapat melihat mana yang menumpuk. Satu rentang yang hilang di wiki adalah yang 06D6-06DClain 0730-0749.

MEMPERBARUI:

Berikut regex yang diperbarui yang seharusnya mengeluarkan semua zalgo termasuk yang dilewati dalam kisaran '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,})

Bagian tersulit adalah mengidentifikasinya, setelah Anda melakukannya - ada banyak solusi termasuk beberapa yang bagus di atas.

Semoga ini menghemat waktu Anda.

Matas Vaitkevicius
sumber
Saya akan mengatakan, jangan sampai spam ini spam!
Praveen Kumar Purushothaman
@PraveenKumar Maukah Anda menjelaskan apa yang Anda maksud?
Matas Vaitkevicius
Saya menghargai jawaban Anda, tetapi ini adalah pertanyaan yang tidak terjawab. Jadi mengapa tidak perlu menambahkan jawaban baru? Itu hanya pandangan saya. Apalagi jawaban Anda bukan JavaScript, bukan?
Praveen Kumar Purushothaman
4
@PraveenKumar Ini mengungkap mengapa validasi zalgo normal ([\u0300–\u036F\u1AB0–\u1AFF\u1DC0–\u1DFF\u20D0–\u20FF\uFE20–\uFE2F]{2,})tidak berfungsi. Tidakkah Anda merasa menarik bahwa menumpuk unicode tidak terbatas pada whats di wiki? Apa yang Anda maksud dengan 'pertanyaan terjawab yang hilang'? EDIT : Anda mungkin merasa aneh untuk menambahkan jawaban atas pertanyaan berusia 3 tahun, tetapi karena saya butuh beberapa saat untuk mencari tahu mengapa jenis zalgo ini berhasil, saya tidak bisa membiarkan pengetahuan seperti itu sia-sia. Orang berikutnya akan menghemat waktu.
Matas Vaitkevicius
7
@PraveenKumar pertanyaan tidak menyebutkan bahasa, dan memposting jawaban baru untuk pertanyaan lama sepenuhnya sesuai jika jawaban lama kurang dalam beberapa hal. Sayangnya saya tidak memiliki cukup pengalaman dengan masalah ini, atau akan mendapat upvote dari saya.
Mark Ransom