93

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

これらは最近Facebookのコメントセクションに表示されました。

どうすればこれを消毒できますか?

4

4 に答える 4

81

これらのUnicode文字はどうしたのですか?

これは、一連の結合文字を持つ文字です。問題の結合文字は基本文字の上に移動したいので、それらは(文字通り)スタックします。たとえば、

ก้้้้้้้้้้้้้้้้้้้้</p>

...これはก(タイ語の文字ko kai)(U + 0E01)の後に、タイ語の結合文字mai thoU + 0E49)のコピーが20個続きます。

どうすればこれを消毒できますか?

テキストを前処理して、1つの文字に適用できる結合文字の数を制限することもできますが、その努力は見返りの価値がない場合があります現在のすべての文字のデータシートが必要なので、それらが組み合わされているかどうかがわかります。また、一部の言語は1つのベースに複数の発音区別符号を使用して記述されているため、少なくともいくつかを許可する必要があります。 。ここで、コメントをラテン文字セットに制限する場合は、範囲チェックが簡単になりますが、もちろん、コメントを少数の言語に制限する場合のオプションにすぎません。詳細、コードシートなどはunicode.orgにあります。

ところで、あるキャラクターがどのように作曲されたか知りたい場合は、最近別の質問として、JSBinに「UnicodeShowMe 」ページを作成しました。テキストをコピーしてテキスト領域に貼り付けるだけで、テキストを構成するすべてのコードポイント(〜文字)が表示され、上記のような各文字を説明するページへのリンクが表示されます。これは、JavaScriptで記述されており、JavaScriptでU + FFFFを超える文字を処理するため、U + FFFF以下の範囲のコードポイントでのみ機能します(JavaScriptでは、 「キャラクター」は常に16ビット。これは、一部の言語では、文字を2つの別々のJavaScript「文字」に分割できることを意味しますが、私はそれを考慮していません)が、ほとんどのテキストには便利です...

于 2012-05-02T13:42:44.883 に答える
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");

これは印刷されます:

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

于 2013-03-12T18:33:33.193 に答える
14

「これをどのように消毒できるか」は、上記のTJクラウダーが最もよく答えています。

ただし、サニタイズは間違ったアプローチだと思います。Cristyはoverflow:hidden cssを含む要素で それを正しく行っています。

少なくとも、それが私がそれを解決している方法です。

于 2013-03-12T18:00:08.830 に答える
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>");
    }

生成されたテーブルを見ると、どのテーブルがスタックしているかを確認できるはずです。ウィキに欠けている範囲の1つは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,})

最も難しいのは、それらを特定することです。一度それを実行すると、上記のいくつかの優れたソリューションを含む多数のソリューションがあります。

これで時間を節約できれば幸いです。

于 2016-03-17T12:38:48.923 に答える