Emoji sind schwerer, als sie aussehen: warum es für „einfach die Emoji entfernen“ keine Einzeiler-Antwort gibt
Veröffentlicht am 29.9.2025 · 11 Min. Lesezeit · Text- & Sprach-Tools
Daniel Okonkwo — Front-end-Entwickler und Tech-Redakteur bei OneKitly
Web-Performance · Dateiformate
Anhand von 5 Quellen geprüft
Es gibt keinen einfachen regulären Ausdruck zum Entfernen von Emoji, weil es keine einfache Definition davon gibt, was ein Emoji ist. Ein einziges Bild auf dem Schirm kann ein Codepunkt sein (😀 ist U+1F600), ein Grundzeichen plus ein unsichtbarer Variantenselektor (❤️ ist U+2764 U+FE0F), eine Basis plus ein Hautton-Modifikator (👍🏽 ist U+1F44D U+1F3FD), eine Kette von Zeichen, verbunden durch Verbinder ohne Breite (👨👩👧👦 sind sieben Codepunkte und elf UTF-16-Einheiten), ein Paar Regionalindikatoren (🇵🇹 ist U+1F1F5 U+1F1F9) oder eine Tag-Sequenz aus sieben Codepunkten. Auch die Eigenschaften, zu denen man greift, passen nicht zusammen: \p{Emoji} trifft die ASCII-Ziffern 0 bis 9 sowie # und *, sodass ein damit gesäuberter Satz seine Zahlen verliert — wir haben es laufen lassen, und aus dem Satz 2026 revenue up 40% wurde revenue up %. \p{Extended_Pictographic} ist die richtige Eigenschaft für Bilder, deckt aber weder Hauttöne noch Flaggen ab. Was funktioniert: den Text in Graphemcluster zerlegen und ganze Cluster entfernen. Dieselbe Regel repariert das Kürzen, bei dem ein Schnitt an einem Codeeinheiten-Index eine vierköpfige Familie in zwei fremde Personen zerlegen oder ein halbes Zeichen hinterlassen kann, aus dem U+FFFD wird.
Ein sichtbares Emoji kann ein Codepunkt sein oder vierzehn UTF-16-Einheiten. Wir haben drei verbreitete reguläre Ausdrücke auf einen echten Satz losgelassen, und jeder ist anders gescheitert — einer löschte die Ziffern. Hier steht, warum, welche Unicode-Eigenschaft welche Frage beantwortet, und welche Graphemcluster-Regel wirklich funktioniert.
Ein Bild, sechs verschiedene Bauweisen
Fragt man ein Programm, wie lang ein Emoji ist, bekommt man je nach Einheit drei Antworten. Wir haben dieselben acht Emoji dreifach gemessen: in UTF-16-Codeeinheiten, was JavaScripts .length meldet; in Codepunkten; und in Graphemclustern, was eine Leserin ein Zeichen nennen würde. Die Graphemzahl ist bei jedem einzelnen 1. Die beiden anderen reichen von 1 bis 14.
Der einfache Fall ist ein einzelner Codepunkt: 😀 ist U+1F600, zwei UTF-16-Einheiten, weil es außerhalb der Basic Multilingual Plane liegt. Dann wird es interessant. ❤️ ist U+2764 gefolgt von U+FE0F, einem unsichtbaren Variantenselektor, dessen einzige Aufgabe lautet: zeichne das vorige Zeichen als Bild, nicht als Symbol. 1️⃣ sind drei Codepunkte: die ASCII-Ziffer 1, derselbe Selektor und U+20E3 COMBINING ENCLOSING KEYCAP. 👍🏽 ist ein Daumen hoch gefolgt von U+1F3FD, einem Hautton-Modifikator, der selbst ein gültiges Zeichen ist und allein als farbiges Quadrat erscheint.
Die schweren Fälle sind Sequenzen. 👨👩👧👦 sind ein Mann, eine Frau, ein Mädchen und ein Junge, getrennt durch drei Kopien von U+200D ZERO WIDTH JOINER: sieben Codepunkte, elf UTF-16-Einheiten, ein Bild. 👩💻 ist eine Frau plus ein Laptop, gleich verbunden, und 🏴☠️ eine schwarze Flagge, verbunden mit einem Totenkopf, dahinter ein Variantenselektor. Flaggen funktionieren noch einmal anders: 🇵🇹 ist gar kein Flaggenzeichen, sondern das Paar Regionalindikatoren U+1F1F5 U+1F1F9, also die Buchstaben P und T in einem Sonderalphabet, und 🏴 ist eine schwarze Flagge, gefolgt von fünf unsichtbaren Tag-Zeichen, die einen Verwaltungscode buchstabieren, plus Abschluss — sieben Codepunkte, vierzehn UTF-16-Einheiten.
Die Eigenschaft, die richtig aussieht und deine Zahlen löscht
JavaScript und jede Regex-Engine mit Unicode-Eigenschafts-Escapes bietet \p{Emoji} an. Es ist die naheliegende Wahl und die falsche. Emoji ist eine Zeicheneigenschaft mit der Bedeutung: dieses Zeichen kann an einem Emoji beteiligt sein — und die Ziffern 0 bis 9 sind beteiligt, sie sind die Basen der Keycap-Sequenzen. # und * ebenso, aus demselben Grund.
Die Folge lässt sich leicht vorführen. Nimm den Satz 2026 revenue up 40%, der überhaupt kein Emoji enthält, und führe replace(/\p{Emoji}/gu, "") aus. Zurück kommt: revenue up %. Alle Ziffern sind fort; das Prozentzeichen, das keine Emoji-Komponente ist, bleibt. Derselbe Ausdruck macht aus Order #7 shipped ✅ ein Order shipped. Nimm stattdessen \p{Extended_Pictographic} für den ersten Satz, und er kommt unverändert zurück — das gewünschte Verhalten.
Doch auch Extended_Pictographic ist keine vollständige Antwort, denn sie bedeutet: dieses Zeichen ist ein Piktogramm — und mehrere Teile eines Emoji sind keine. Wir haben jeden Teil geprüft: Der Hautton-Modifikator U+1F3FD ist nicht Extended_Pictographic, die Regionalindikatoren einer Flagge ebenso wenig. Lässt man Extended_Pictographic allein über einen Satz mit 🇵🇹 und 👍🏽 laufen, überlebt die Flagge ganz, während der Daumen verschwindet und seinen Hautton als einzelnes farbiges Quadrat zurücklässt.
Emoji_Presentation ist die Eigenschaft, die beantwortet, ob etwas als Bild erscheint
Manche Zeichen erscheinen standardmäßig als farbiges Bild, andere standardmäßig als einfarbiger Text. Genau diesen Unterschied hält Emoji_Presentation fest. Wir haben eine Reihe von Zeichen geprüft, und die Trennung ist sauber: 😀, ⌚, 👍 und 🀄 haben Emoji_Presentation und erscheinen ohne Zutun als Bild. ❤, ☺, ▶, ✔, ©, ® und ™ haben sie nicht; allein gelassen erscheinen sie als Textglyphen in der umgebenden Schrift.
Dafür gibt es den Variantenselektor. U+FE0F ist die Aufforderung, das vorige Zeichen als Emoji darzustellen, und er macht aus ❤ ein ❤️ und aus ▶ ein ▶️. Er ist zugleich unsichtbar, im Kopf der Leserin gewichtslos und in der Zeichenkette ein echtes Zeichen — daher das verwaiste U+FE0F, das eine Regex hinterlässt, die das Piktogramm entfernt, den Selektor aber nicht. Wir haben es gemessen: done ❤️ ohne die Extended_Pictographic kommt als sechs Codepunkte zurück: d, o, n, e, Leerzeichen, U+FE0F. Das Ergebnis sieht sauber aus und ist es nicht.
Drei naive reguläre Ausdrücke, drei verschiedene Fehlschläge
Wir haben einen Satz genommen — Shipping to 🇵🇹 today 👨👩👧👦 — 40% off, thanks 👍🏽 #7 ❤️, das sind 63 UTF-16-Einheiten, 55 Codepunkte und 46 Graphemcluster — und die drei üblichen Ansätze laufen lassen, dazu einen vierten auf Basis von Graphemclustern.
Der Ansatz über einen Codepunktbereich, /[\u{1F300}-\u{1FAFF}]/gu, steht in der Hälfte der Antworten im Netz. Er entfernte die Familienmitglieder und den Daumen, doch die Flagge überlebte, weil Regionalindikatoren bei U+1F1E6–U+1F1FF liegen, unterhalb des Bereichs; das Herz überlebte, weil U+2764 weit darunter liegt; und die drei Verbinder ohne Breite, die die Familie zusammenhielten, blieben als unsichtbarer Müll in der Zeichenkette.
Der \p{Emoji}-Ansatz entfernte Flagge, Familie und Daumen — und dazu die 40 und die 7 aus #7, übrig blieben % off und ein nacktes Rautezeichen. Der Extended_Pictographic-Ansatz ließ die Flagge unversehrt, entfernte den Daumen, nicht aber seinen Hautton, und ließ Verbinder und Variantenselektor stehen. Drei plausible Einzeiler, drei verschiedene Arten falscher Ausgabe, und keine meldet ein Problem.
Der vierte Ansatz zerlegt den Text mit Intl.Segmenter in Graphemcluster und verwirft dann einen ganzen Cluster, sobald er einen Regionalindikator, ein Zeichen mit Emoji_Presentation oder ein Piktogramm gefolgt vom Variantenselektor enthält. Auf demselben Satz kam zurück: Shipping to today — 40% off, thanks #7 — Ziffern erhalten, Flagge als Einheit entfernt, keine verwaisten Verbinder, kein versprengter Selektor. Das einzige Artefakt sind die doppelten Leerzeichen dort, wo die Emoji standen, was ein zweiter Durchgang zum Zusammenfalten von Leerraum behebt.
Beim Kürzen schlägt es in der Produktion zu
Eine Zeichenkette bei N Einheiten abzuschneiden ist mit Abstand die häufigste Art, Emoji zu zerbrechen, weil sie am billigsten zu schreiben ist und bei jeder Teststring funktioniert, die einer englischsprachigen Entwicklerin einfällt. Nimm Great work 👨👩👧👦 thanks, 29 UTF-16-Einheiten. Ein Schnitt bei 12, 15 oder 18 endet auf einer einzelnen hohen Ersatzeinheit — einem halben Zeichen, das kein gültiger Text ist. Durch UTF-8 geschickt werden daraus die drei Bytes EF BF BD, das Ersatzzeichen, und die Leserin sieht eine schwarze Raute. isWellFormed() liefert in JavaScript für diese Zeichenkette false, ein billiger Weg, den Fehler in einem Test zu fangen.
Der subtilere Fehlschlag ist schlimmer, weil er gültigen Text erzeugt, der etwas anderes bedeutet. Schneidet man dieselbe Zeichenkette bei 16 Einheiten, ergibt sich Great work 👨👩 — aus der vierköpfigen Familie sind ein Mann und eine Frau mit einem Verbinder dazwischen geworden, was keine definierte Sequenz ist und deshalb als zwei getrennte Personen erscheint. Nichts ist fehlerhaft. Nichts wirft eine Ausnahme. Die Nachricht zeigt jetzt ein anderes Bild als das gesendete.
Nach Codepunkten zu iterieren, etwa mit dem Spread-Operator, behebt das Problem der halben Einheit, das andere nicht: Die ersten 14 Codepunkte derselben Zeichenkette ergeben weiterhin Great work 👨👩. Nur Graphemcluster treffen es, denn sie sind die Einheit, die der Segmentierungsalgorithmus als ein vom Nutzer wahrgenommenes Zeichen definiert. Die ersten 14 Graphemcluster ergeben Great work 👨👩👧👦 t — die ganze Familie als eine Einheit erhalten, was eine Leserin von einer Vorschau über vierzehn Zeichen erwarten würde.
Emoji zu zählen hat dasselbe Problem wie sie zu entfernen
Nimm die Zeichenkette 🇵🇹 👨👩👧👦 👍🏽 ❤️ 😀. Ein Mensch zählt fünf Emoji. Wir haben sechs verschiedene Methoden gefragt und sechs verschiedene Antworten bekommen: 27 UTF-16-Einheiten, 18 Codepunkte, 9 Graphemcluster, 5 nicht-leere Graphemcluster, 7 Treffer für \p{Extended_Pictographic}, 9 für \p{Emoji_Presentation} und 10 für \p{Emoji}. Nur eine davon ist 5.
Die Eigenschaftszählungen sind aus genau den obigen Gründen hoch: Die Familie steuert vier Piktogramme bei, der Daumen eines und sein Hautton unter Emoji_Presentation ein weiteres, die Flagge zwei. Wenn dein Produkt eine Regel wie höchstens drei Emoji pro Beitrag durchsetzt, taugt die Regel nur so viel wie der Zähler dahinter, und der Zähler muss derjenige sein, der der Leserin recht gibt: Graphemcluster, die ein Emoji-Zeichen enthalten.
Was das Entfernen von Nicht-ASCII stattdessen tut und warum es eine andere Aufgabe ist
Eine verlockende Abkürzung ist, nur ASCII zu behalten, mit dem Argument, alle Emoji lägen außerhalb. Das tun sie — und der Großteil der übrigen Welt ebenfalls. Wir haben replace(/[^\x00-\x7F]/g, "") auf Café ☕ — résumé sent 👍 laufen lassen, heraus kam Caf rsum sent. Tasse und Daumen sind weg, aber ebenso das é in Café, beide Akzente in résumé und der Geviertstrich. In einem französischen, spanischen, portugiesischen, deutschen oder italienischen Satz zerstört das gewöhnliche Wörter, keine Zierde.
Die beiden Vorgänge gehören aus gutem Grund in verschiedene Werkzeuge. Emoji entfernen heißt: nimm die Bilder heraus und lass die Sprache in Ruhe. Nicht-ASCII entfernen heißt: reduziere das auf die 128 Zeichen, die ein altes System verkraftet — eine Transliterationsaufgabe mit echten Verlusten, die man bewusst wählen sollte. Zum zweiten zu greifen, wenn man das erste wollte, ist eine der leiseren Arten, ein mehrsprachiges Produkt zu zerbrechen.
| Emoji | Wie es gebaut ist | UTF-16-Einheiten | Codepunkte | Graphemcluster |
|---|---|---|---|---|
| 😀 | Ein einzelner Codepunkt, U+1F600 | 2 | 1 | 1 |
| ❤️ | Basis U+2764 plus Variantenselektor U+FE0F | 2 | 2 | 1 |
| 1️⃣ | Ziffer 1, Selektor U+FE0F, Keycap U+20E3 | 3 | 3 | 1 |
| 👍🏽 | Basis U+1F44D plus Hautton-Modifikator U+1F3FD | 4 | 2 | 1 |
| 🇵🇹 | Zwei Regionalindikatoren, U+1F1F5 U+1F1F9 | 4 | 2 | 1 |
| 👨👩👧👦 | Vier Personen, verbunden durch drei U+200D-Verbinder | 11 | 7 | 1 |
| 🏴 | Schwarze Flagge plus fünf Tag-Zeichen plus Abschluss | 14 | 7 | 1 |
Häufige Fragen
- Was ist der kürzeste reguläre Ausdruck, der Emoji korrekt entfernt?
- Es gibt keinen, und das ist die ehrliche Antwort. Eine Regex trifft Codepunkte, und ein Emoji ist eine Folge von Codepunkten, deren Grenzen ein Segmentierungsalgorithmus festlegt, kein Muster. Man kommt mit einer langen Alternation aus Piktogrammen, Verbinderketten, Regionalindikatorpaaren und Modifikatoren nahe heran, implementiert dann aber den Algorithmus schlecht nach. Erst segmentieren, dann Cluster filtern — drei Zeilen, und es stimmt.
- Warum blieb nach dem Entfernen der Emoji ein unsichtbares Zeichen zurück?
- Weil du das Bild entfernt hast, seine Begleiter aber nicht. Die beiden üblichen Verdächtigen sind U+FE0F, der Variantenselektor, der die Emoji-Darstellung anfordert, und U+200D, der Verbinder ohne Breite, der die Teile einer Sequenz verknüpft. Keiner ist ein Piktogramm, ein piktogrammbasierter Filter lässt sie also stehen. Auf dem Schirm unsichtbar, in der Zeichenkette real: Sie zählen gegen Zeichenlimits, brechen Gleichheitsvergleiche und überraschen die nächste Person, die den Text vergleicht.
- Warum sieht dasselbe Emoji auf einem anderen Telefon anders aus?
- Die Zeichenkette trägt die Identität, nicht die Zeichnung. Jeder Hersteller liefert seine eigene Emoji-Schrift, also ist U+1F600 auf einer Plattform das Lächeln eines Zeichners und anderswo das eines anderen. Fehlt einem Gerät die Glyphe für eine Sequenz, zeichnet es die Teile: Eine Familie, die auf deinem Telefon ein Bild ist, kann auf einem älteren Gerät als vier getrennte Personen erscheinen — das korrekte Ausweichverhalten für eine Verbindersequenz, kein Fehler.
- Wie sollte ein Zeichenlimit ein Emoji zählen?
- Zähle Graphemcluster, wenn das Limit für die Leserin da ist, und Bytes, wenn es für den Speicher da ist. Die beiden Antworten unterscheiden sich bei einem Familien-Emoji um den Faktor elf; wähle also die, die zum Grund des Limits passt, und schreibe neben das Feld, welche es ist. Was du nie tun solltest: stillschweigend eine UTF-16-Länge durchsetzen, denn wer drei Flaggen tippt, stößt bei zwölf sichtbaren Zeichen ohne Erklärung an ein Limit von 30.
- Sind © und ™ Emoji?
- Nach den Eigenschaften ja und nein zugleich — genau die Verwirrung, um die es hier geht. Wir haben beide geprüft: Jedes hat Emoji und Extended_Pictographic, aber keines hat Emoji_Presentation, beide erscheinen also als gewöhnlicher Text, sofern kein Variantenselektor ein Bild verlangt. Ein Filter auf Basis von Extended_Pictographic löscht damit das Copyright-Zeichen aus deiner Fußzeile. Willst du nur die farbigen Bilder, prüfe auf Emoji_Presentation oder auf ein Piktogramm, dem unmittelbar U+FE0F folgt.
- Ändert das Entfernen von Emoji die Bedeutung einer Nachricht?
- Oft, und das spricht dafür, sie an den Rändern eines Systems zu entfernen und nicht in der Mitte. Emoji tragen Tonfall, Verneinung und manchmal den gesamten Inhalt einer Antwort. Sie zu entfernen ist angemessen, wenn das Ziel sie nicht darstellen kann — ein Klartext-Export, eine alte Datenbankspalte, ein gedruckter Bericht, ein Dateiname — und unangemessen, wenn der Text weiterhin von einem Menschen gelesen wird. Beim Hinausgehen entfernen, das Original gespeichert lassen.
Artikel, die dich interessieren könnten
Alle Ratgeber →Ähnliche Tools
Quellen
- Unicode Consortium — UTS #51: Unicode Emoji — emoji properties, ZWJ sequences, modifiers and flags
- Unicode Consortium — UAX #29: Unicode Text Segmentation — grapheme cluster boundaries
- Mozilla — MDN Web Docs — Unicode character class escapes in regular expressions
- Mozilla — MDN Web Docs — Intl.Segmenter
- Ecma International — ECMA-402: ECMAScript Internationalization API Specification
Hast du einen Fehler in diesem Artikel entdeckt?