Was ist mit diesen Unicode-Kombinationszeichen los und wie können wir sie filtern?


91

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

Diese wurden kürzlich in Facebook-Kommentarbereichen angezeigt.

Wie können wir das sanieren?


5
Haben Sie diese Frage noch nicht gestellt? (Ehrliche Frage.)
Ry-

5
Das sind definitiv keine ASCII
Chris Eberle

31
Warum die Schlussstimmen? Es ist eine programmierbezogene Frage, da ich wissen möchte, wie diese Art von Eingabe
bereinigt werden kann,

17
So ก้้้้้้้้้้้้้้้้้้้้ ก้้้้้้้้้้้้้้้้้้้้ will กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้ ก็็็็็็็็็็็็็็็็็็็็ กิิิิิิิิิิิิิิิิิิิิ ก้้้้้้้้้้้้้้้้้้้้ กิิิิิิิิิิิิิิิิิิิิ. Tatsächlich kann ein Beitrag, der diese Zeichen veröffentlicht, ohne Bereinigung den Kommentar darüber unlesbar machen, was überhaupt keine angenehme Benutzererfahrung ist.
XCS

14
@pjotr Es ist definitiv kein Browser-Fehler. Wenn Sie möchten, dass die Zeichen das enthaltende Feld nicht überlaufen, können Sie dies einfach mit CSS lösen (Überlauf: versteckt;) ...
XCS

Antworten:


80

Was ist mit diesen Unicode-Zeichen los?

Das ist ein Charakter mit einer Reihe von kombinierten Charakteren . Da die fraglichen kombinierenden Zeichen über das Basiszeichen hinausgehen möchten, stapeln sie sich (im wahrsten Sinne des Wortes). Zum Beispiel der Fall von

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

... es ist ein ก (thailändisches Zeichen ko kai ) ( U + 0E01 ), gefolgt von 20 Kopien des thailändischen Kombinationszeichens mai tho ( U + 0E49 ).

Wie können wir das sanieren?

Sie können den Text und begrenzen die Anzahl der Kombinationszeichen Vorprozess, die auf ein einzelnes Zeichen angewendet werden kann, aber der Aufwand ist vielleicht nicht die Belohnung wert sein. Sie benötigen die Datenblätter für alle aktuellen Zeichen, damit Sie wissen, ob sie kombiniert wurden oder was, und Sie müssen mindestens einige zulassen, da einige Sprachen mit mehreren diakritischen Zeichen auf einer einzigen Basis geschrieben sind . Wenn Sie Kommentare auf den lateinischen Zeichensatz beschränken möchten, ist dies eine einfachere Bereichsprüfung. Dies ist jedoch nur dann eine Option, wenn Sie Kommentare auf wenige Sprachen beschränken möchten. Weitere Informationen, Codeblätter usw. unter unicode.org .

Übrigens, wenn Sie jemals wissen wollen, wie ein Charakter zusammengesetzt wurde, habe ich kürzlich für eine andere Frage eine schnelle und schmutzige "Unicode Show Me" -Seite auf JSBin codiert. Sie kopieren einfach den Text und fügen ihn in den Textbereich ein. Daraufhin werden alle Codepunkte (~ Zeichen) angezeigt, aus denen der Text besteht, mit Links wie den oben genannten zu der Seite, auf der die einzelnen Zeichen beschrieben werden. Es funktioniert nur für Codepunkte im Bereich U + FFFF und darunter, da es in JavaScript geschrieben ist und um Zeichen über U + FFFF in JavaScript zu verarbeiten, müssen Sie mehr Arbeit leisten, als ich für diese Frage wollte (weil in JavaScript a "Charakter" ist immer 16 Bit, was bedeutet, dass für einige Sprachen ein Zeichen auf zwei separate JavaScript- "Zeichen" aufgeteilt werden kann und ich das nicht berücksichtigt habe), aber es ist praktisch für die meisten Texte ...


1
Würden Sie nicht einfach wiederholte Kopien desselben kombinierten Codepunkts hintereinander in einer einzigen Kopie löschen? Wann müssten Sie jemals denselben Codepunkt mehr als einmal auf einem Basiscodepunkt kombinieren?
Remy Lebeau

4
@RemyLebeau: "Wann müssten Sie jemals denselben Codepunkt mehr als einmal auf einem Basiscodepunkt kombinieren?" Ich weiß nicht, ich weiß sehr, sehr wenig darüber, wie Sie andere Sprachen schreiben - zum Beispiel Thai. Es würde mich überhaupt nicht überraschen, herauszufinden, dass in einigen Fällen mehr als ein Codepunkt gültig war. Dies verringert jedoch nicht die Komplexität. Sie benötigen noch eine der Unicode-Tabellen, um herauszufinden, welche Zeichen kombiniert werden.
TJ Crowder

Ich habe Ihre Seite dazu gebracht, die Unicode-Zeichenfolge von der URL zu akzeptieren, z. B. jsbin.com/erajer/7/…
ubershmekel

2
JavaScript-Bibliothek zum einfachen Entfernen von Unicode-Kombinationsmarken aus Zeichenfolgen: mths.be/stripcombiningmarks
Mathias Bynens

JavaScript verwendet UTF-16 mit « Ersatzpaaren »
Dolmen

17

Wenn Sie eine Regex-Engine mit anständiger Unicode-Unterstützung haben, ist es trivial, diese Art von Zeichenfolgen zu bereinigen. In Perl können Sie beispielsweise alle bis auf die erste Kombinationsmarke von jedem (vom Benutzer wahrgenommenen) Zeichen wie folgt entfernen:

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

Dies wird gedruckt:

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


9
Ich kann kein Tibetisch lesen, aber ich bin besorgt, dass dieser Brute-Force-Ansatz die Funktionalität der Sprachgestaltung beeinträchtigen könnte. Ich habe Unicode gesehen, das legitime Anwendungsfälle von mehr als einer Kombinationsmarke aufweist. Arabisch ist ein gutes Beispiel. Ich werde versuchen, mich daran zu erinnern, dies von meinen tibetischen Mitarbeitern zu leiten.
FlipMcF

2
Sie haben Recht, es gibt sicherlich Fälle, in denen mehrere Kombinationsmarken legitim sind. Sie können den regulären Ausdruck jedoch leicht ändern, um ein bestimmtes Maximum an Markierungen zuzulassen.
Nwellnhof

Upvoted, weil es die Frage "Wie bereinigen Sie diese?" Beantwortet. Aber ich denke, das wäre ein Alptraum für die Instandhaltung.
FlipMcF

Außerdem entfernt der RE nur benachbarte Duplikate. Es würde nicht aufräumen, sagen wir : <base><macron><overline><macron><overline>.... Wenn Ihr Text also mehrere verschiedene Kombinationszeichen benötigt, wird er gut durchlaufen. und bösartiger Text könnte noch erstellt werden.
Jesse Chisholm

13

"Wie können wir das desinfizieren?" Wird am besten oben von TJ Crowder beantwortet

Ich denke jedoch, dass Desinfektion der falsche Ansatz ist, und Cristy hat es richtig mit overflow:hiddendem CSS-haltigen Element.

Zumindest löse ich das so.


6

Ok, ich habe eine Weile gebraucht, um das herauszufinden. Ich hatte den Eindruck, dass die Kombination von Charakteren zur Herstellung von Zalgo auf diese beschränkt ist . Also erwartete ich, dass Regex die Freaks fangen würde.

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

und es hat nicht funktioniert ...

Der Haken ist, dass die Liste im Wiki nicht die gesamte Bandbreite der kombinierten Zeichen abdeckt.

Was mir einen Hinweis gab, ist "ก้้้้้้้้้้้้้้้้้้้้".charCodeAt(2).toString(16)= "e49", was nicht in einem Kombinationsbereich liegt, sondern in den "privaten Gebrauch" fällt.

In C # fallen sie unter UnicodeCategory.NonSpacingMarkund das folgende Skript löscht sie aus:

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

Wenn Sie sich die generierte Tabelle ansehen, sollten Sie sehen können, welche stapeln. Ein Bereich, der im Wiki fehlt, ist ein 06D6-06DCanderer 0730-0749.

AKTUALISIEREN:

Hier ist ein aktualisierter Regex , der alle Zalgo herausfischen sollte, einschließlich derjenigen, die im "normalen" Bereich umgangen wurden.

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

Am schwierigsten ist es, sie zu identifizieren, sobald Sie dies getan haben - es gibt eine Vielzahl von Lösungen, einschließlich einiger guter oben.

Hoffe das spart dir etwas Zeit.


Ich würde sagen, diesen Spam nicht zu spammen!
Praveen Kumar Purushothaman

@PraveenKumar Möchten Sie näher erläutern, was Sie meinen?
Matas Vaitkevicius

Ich schätze Ihre Antwort, aber dies ist eine verlorene beantwortete Frage. Warum also unnötig neue Antworten hinzufügen? Es ist nur meine Ansicht. Außerdem ist Ihre Antwort nicht JavaScript, oder?
Praveen Kumar Purushothaman

4
@PraveenKumar Es wird aufgedeckt, warum die normale Zalgo-Validierung ([\u0300–\u036F\u1AB0–\u1AFF\u1DC0–\u1DFF\u20D0–\u20FF\uFE20–\uFE2F]{2,})nicht funktioniert. Finden Sie es nicht interessant, dass das Stapeln von Unicode nicht auf das beschränkt ist, was im Wiki vorhanden ist? Was meinst du mit "verlorene beantwortete Frage"? EDIT : Es mag seltsam sein, eine Antwort auf eine 3 Jahre alte Frage hinzuzufügen, aber da ich eine Weile gebraucht habe, um herauszufinden, warum diese Art von Zalgo funktioniert, konnte ich nicht zulassen, dass dieses Wissen verschwendet wurde. Der nächste Typ wird etwas Zeit sparen.
Matas Vaitkevicius

7
@PraveenKumar Die Frage gibt keine Sprache an, und das Posten einer neuen Antwort auf eine alte Frage ist völlig angemessen, wenn die alten Antworten in irgendeiner Weise mangelhaft waren. Leider habe ich nicht genug Erfahrung mit diesem Problem, sonst würde es eine positive Bewertung von mir bekommen.
Mark Ransom
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.