Bu Unicode karakterleri birleştirmede ne var ve onları nasıl filtreleyebiliriz?


91

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

Bunlar son zamanlarda facebook yorum bölümlerinde göründü.

Bunu nasıl sterilize edebiliriz?


5
Bu soruyu daha önce sormadın mı? (Dürüst soru.)
Ry-

5
Bunlar kesinlikle ascii değil
Chris Eberle

31
Neden kapanış oyları? Bu, programlama ile ilgili bir soru, çünkü bu tür girdileri nasıl temizleyeceğimi bilmek istiyorum, böylece web sitemdeki yorum bölümleri 13 yaşındaki çocukların oyun alanı
olmayacak

17
กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้ ก็็็็็็็็็็็็็็็็็็็็ ก็็็็็็็็็็็็็็็็็็็็ กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้ ก็็็็็็็็็็็็็็็็็็็็ กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้ กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้ ก็็็็็็็็็็็็็็็็็็็็ ก็็็็็็็็็็็็็็็็็็็็ กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้ ก็็็็็็็็็็็็็็็็็็็็ กิิิิิิิิิิิิิิิ "yani web sitemdeki yorum bölümleri 13 yaşındaki çocukların oyun alanı olmayacak." Aslında sterilizasyon olmadan bu karakterlerin yazılması yukarıdaki yorumu okunamaz hale getirebilir ki bu hiç de hoş bir kullanıcı deneyimi değildir.
XCS

14
@pjotr Kesinlikle bir tarayıcı hatası değil. Karakterlerin içeren kutudan
taşmamasını

Yanıtlar:


80

Bu unicode karakterlerin nesi var?

Bu, bir dizi birleştirici karakter içeren bir karakter . Söz konusu birleştirici karakterler temel karakterin üstüne çıkmak istedikleri için, yığılırlar (kelimenin tam anlamıyla). Örneğin, durumu

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

... bir ก (Tay karakteri ko kai ) ( U + 0E01 ) ve ardından Tayca birleştirme karakteri mai tho ( U + 0E49 ) ' un 20 kopyası gelir .

Bunu nasıl sterilize edebiliriz?

Sen olabilir -öncesi işlemek metin ve tek bir karakter uygulanabilir birleştirerek karakter sayısını sınırlamak, ama çabaya değer ödül olmayabilir. Mevcut tüm karakterler için veri sayfalarına ihtiyacınız olacak, böylece bunların bir araya gelip gelmediğini bilmeniz gerekir ve en azından birkaçına izin vermeniz gerekir, çünkü bazı diller tek bir temelde birkaç aksanla yazılır. . Şimdi, yorumları Latin karakter kümesiyle sınırlamak istiyorsanız, bu daha kolay bir aralık kontrolü olacaktır, ancak elbette bu, yorumları yalnızca birkaç dille sınırlamak istiyorsanız bir seçenek. Unicode.org'da daha fazla bilgi, kod sayfaları vb .

BTW, bir karakterin nasıl bestelendiğini öğrenmek isterseniz, geçenlerde başka bir soru için JSBin'de hızlı ve kirli bir "Unicode Show Me" sayfası kodladım. Metni metin alanına kopyalayıp yapıştırmanız yeterlidir ve bu size metnin oluştuğu tüm kod noktalarını (~ karakterleri) gösterir, her bir karakteri tanımlayan sayfaya yukarıdaki gibi bağlantılar ile. Yalnızca U + FFFF aralığındaki ve altındaki kod noktaları için çalışır, çünkü JavaScript'te yazılmıştır ve JavaScript'te U + FFFF'nin üstündeki karakterleri işlemek için, bu soru için yapmak istediğimden daha fazla iş yapmanız gerekir (çünkü JavaScript'te, "karakter" her zaman 16 bit, yani bazı diller için bir karakter iki ayrı JavaScript "karakterine" bölünebilir ve bunu hesaba katmadım), ancak çoğu metin için kullanışlıdır ...


1
Aynı birleştirme kod noktasının tekrarlanan kopyalarını arka arkaya tek bir kopyaya silmeyecek misiniz? Aynı kod noktasını bir temel kod noktasında birden fazla kez birleştirmeniz ne zaman gerekir?
Remy Lebeau

4
@RemyLebeau: "Aynı kod noktasını bir temel kod noktası üzerinde ne zaman birden fazla birleştirmeniz gerekir?" Bilmiyorum, diğer dilleri nasıl yazdığınız hakkında çok çok az şey biliyorum - örneğin Tayca. Bazılarında aynı kod noktasından birden fazlasının geçerli olduğunu öğrenince hiç şaşırmam. Ancak bunu yapmak karmaşıklığı azaltmaz; hangilerinin karakterleri birleştirdiğini bulmak için hala Unicode tablolarından birine ihtiyacınız var.
TJ Crowder

Sayfanızın url'den unicode dizesini kabul etmesini sağladım
ubershmekel

2
JavaScript kitaplık kolayca Unicode dizeleri gelen işaretleri birleştirerek kaldırmak için: mths.be/stripcombiningmarks
Mathias Bynens

JavaScript UTF-16'yı " vekil çiftlerle " kullanıyor
dolmen

17

Yeterli Unicode desteğine sahip bir regex motorunuz varsa, bu tür dizeleri sterilize etmek önemsizdir. Örneğin Perl'de, aşağıdaki gibi her (kullanıcı tarafından algılanan) karakterden ilk birleştirme işareti dışındaki tüm işaretleri kaldırabilirsiniz:

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

Bu yazdıracak:

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


9
Tibetçe okuyamıyorum, ancak bu kaba kuvvet yaklaşımının, dilin tasarlanma biçiminden işlevselliği kaldırabileceğinden endişeleniyorum. Birden fazla birleştirme işaretinin meşru kullanım durumlarına sahip unicode gördüm. Arapça güzel bir örnek. Bunu Tibetli meslektaşlarım tarafından yürütmeyi hatırlamaya çalışacağım.
FlipMcF

2
Haklısın, birden fazla kombinasyon işaretinin meşru olduğu durumlar kesinlikle var. Ancak, belirli bir maksimum işarete izin vermek için normal ifadeyi kolayca değiştirebilirsiniz.
nwellnhof

"Bunu nasıl sterilize edersiniz" sorusuna cevap verdiği için oy verildi. Ancak bunun bir bakım kabusu olacağını düşünüyorum.
FlipMcF

Ayrıca, RE sadece bitişik çoğaltmayı kaldırır . Bunu söylemek, temizlemek olmaz: <base><macron><overline><macron><overline>.... Dolayısıyla, metniniz birden çok farklı birleştirme karakterine ihtiyaç duyuyorsa, iyi geçecektir; ve kötü amaçlı metin yine de oluşturulabilir.
Jesse Chisholm

13

"Bunu nasıl sterilize edebiliriz" en iyi yukarıda TJ Crowder tarafından yanıtlanmıştır.

Bununla birlikte, sanitasyonun yanlış bir yaklaşım olduğunu düşünüyorum ve Cristy , overflow:hiddencss içeren elementte haklı .

En azından ben böyle çözüyorum.


6

Tamam, bunu anlamam biraz zaman aldı, zalgo üretmek için karakterleri birleştirmenin bunlarla sınırlı olduğu izlenimine kapılmıştım . Bu yüzden, normal ifadeyi takiben ucubeleri yakalamasını bekliyordum .

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

ve işe yaramadı ...

İşin püf noktası, wiki'deki listenin tüm karakter kombinasyonlarını kapsamadığıdır.

Bana bir ipucu veren "ก้้้้้้้้้้้้้้้้้้้้".charCodeAt(2).toString(16)= "e49", birleştirme aralığında değil, 'Özel kullanıma' giriyor.

C # 'da altına düşer UnicodeCategory.NonSpacingMarkve aşağıdaki komut dosyası onları temizler:

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

Oluşturulan tabloya bakarak hangilerinin yığıldığını görebilmelisiniz. Wiki'de eksik olan bir aralık 06D6-06DCdiğeridir 0730-0749.

GÜNCELLEME:

İşte , 'normal' aralıkta atlananlar da dahil olmak üzere tüm zalgoları yakalaması gereken güncellenmiş normal ifade.

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

İşin en zor kısmı, bunu yaptıktan sonra onları tanımlamaktır - yukarıdakilerden bazılarını içeren çok sayıda çözüm vardır.

Umarım bu size biraz zaman kazandırır.


Bu spam'i spam etmeyin!
Praveen Kumar Purushothaman

@PraveenKumar Ne demek istediğini açıklar mısın?
Matas Vaitkevicius

Cevabınız için minnettarım, ancak bu kayıp cevaplanmış bir soru. Öyleyse neden gereksiz yere yeni cevaplar eklemelisiniz? Bu sadece benim görüşüm. Üstelik cevabınız JavaScript değil, değil mi?
Praveen Kumar Purushothaman

4
@PraveenKumar Normal zalgo doğrulamasının neden çalışmadığını ortaya çıkarır ([\u0300–\u036F\u1AB0–\u1AFF\u1DC0–\u1DFF\u20D0–\u20FF\uFE20–\uFE2F]{2,}). Unicode istiflemenin wiki'de ne ile sınırlı olmaması sizce ilginç değil mi? 'Kayıp cevaplanmış soru' ile neyi kastediyorsunuz? DÜZENLEME : 3 yıllık bir soruya cevap eklemeyi tuhaf bulabilirsiniz, ancak bu tür zalgo'nun neden işe yaradığını anlamam biraz zaman aldığından, bu tür bilgilerin boşa gitmesine izin veremezdim. Sıradaki adam biraz zaman kazanacak.
Matas Vaitkevicius

7
@PraveenKumar soru bir dil belirtmiyor ve eski bir soruya yeni bir cevap göndermek, eğer eski cevaplar bir şekilde eksikse tamamen uygundur. Maalesef bu sorunla ilgili yeterli tecrübem yok, yoksa benden olumlu oy alacaktı.
Mark Ransom
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.