Für einige Testzwecke benötige ich eine Zeichenfolge mit ungültigen Unicode-Zeichen. Wie erstelle ich einen solchen String in Zsh?
Ich nehme an, Sie meinen UTF-8-codierte Unicode-Zeichen.
Das hängt davon ab, was Sie unter ungültig verstehen .
invalid_byte_sequence=$'\x80\x81'
Dies ist eine Folge von Bytes, die für sich genommen in der UTF-8-Codierung nicht gültig ist (für das erste Byte in einem UTF-8-codierten Zeichen sind immer die zwei höchsten Bits gesetzt). Diese Sequenz könnte jedoch in der Mitte eines Zeichens zu sehen sein, so dass sie eine gültige Sequenz bilden könnte, sobald sie mit einer anderen ungültigen Sequenz wie verkettet ist $'\xe1'
. $'\xe1'
oder $'\xe1\x80'
selbst wäre auch ungültig und könnte als abgeschnittenes Zeichen angesehen werden.
other_invalid_byte_sequence=$'\xc2\xc2'
Das 0xc2-Byte würde ein 2-Byte-Zeichen starten, und 0xc2 darf sich nicht in der Mitte eines UTF-8-Zeichens befinden. Diese Sequenz kann also niemals in einem gültigen UTF-8-Text gefunden werden. Gleiches gilt für $'\xc0'
oder für $'\xc1'
Bytes, die in der UTF-8-Codierung niemals vorkommen.
Für die Sequenzen \uXXXX
und \UXXXXXXXX
gehe ich davon aus, dass die Codierung des aktuellen Gebietsschemas UTF-8 ist.
non_character=$'\ufffe'
Dies ist eines der 66 derzeit angegebenen Nichtzeichen .
not_valid_anymore=$'\U110000'
Unicode ist jetzt auf Codepunkte bis 0x10FFFF beschränkt. Und die UTF-8-Codierung, die ursprünglich für bis zu 0x7FFFFFFF ausgelegt war ( perl
unterstützt auch eine Variante, die zu 0xFFFFFFFFFFFFFFFF geht), ist jetzt herkömmlicherweise auch darauf beschränkt.
utf16_surrogate=$'\ud800'
Die Codepunkte 0xD800 bis 0xDFFF sind Codepunkte, die für die UTF16-Codierung reserviert sind. Die UTF-8-Codierung dieser Codepunkte ist daher ungültig.
Jetzt sind die meisten verbleibenden Codepunkte in der neuesten Version von Unicode noch nicht zugewiesen.
unassigned=$'\u378'
Neuere Versionen von Unicode enthalten neue Zeichen. Zum Beispiel hat Unicode 8.0 (veröffentlicht im Juni 2015) 🤗 ( U + 1F917 ), das in früheren Versionen nicht zugewiesen wurde.
unicode_8_and_above_only=$'\U1f917'
Einige Tests mit uconv
:
$ printf %s $invalid_byte_sequence| uconv -x any-name
Conversion to Unicode from codepage failed at input byte position 0. Bytes: 80 Error: Illegal character found
Conversion to Unicode from codepage failed at input byte position 1. Bytes: 81 Error: Illegal character found
$ printf %s $other_invalid_byte_sequence| uconv -x any-name
Conversion to Unicode from codepage failed at input byte position 0. Bytes: c2 Error: Illegal character found
Conversion to Unicode from codepage failed at input byte position 1. Bytes: c2 Error: Truncated character found
$ printf %s $non_character| uconv -x any-name
\N{<noncharacter-FFFE>}
$ printf %s $not_valid_anymore| uconv -x any-name
Conversion to Unicode from codepage failed at input byte position 0. Bytes: f4 90 80 80 Error: Illegal character found
$ printf %s $utf16_surrogate | uconv -x any-name
Conversion to Unicode from codepage failed at input byte position 0. Bytes: ed a0 80 Error: Illegal character found
$ printf %s $unassigned | uconv -x any-name
\N{<unassigned-0378>}
$ printf %s $unicode_8_and_above_only | uconv -x any-name
\N{<unassigned-1F917>}
$
Mit GNU grep
, können Sie verwenden , grep .
um zu sehen , ob es ein Zeichen in der Eingabe finden:
l=(invalid_byte_sequence other_invalid_byte_sequence non_character
not_valid_anymore utf16_surrogate unassigned unicode_8_and_above_only)
for c ($l) print -r ${(P)c} | grep -q . && print $c
Was für mich gibt:
non_character
not_valid_anymore
utf16_surrogate
unassigned
unicode_8_and_above_only
Das heißt, ich grep
betrachte einige dieser ungültigen Zeichen, die keine Zeichen sind oder noch nicht zugewiesen wurden, immer noch als (oder enthaltende) Zeichen. YMMV für andere Implementierungen grep
oder andere Dienstprogramme.
for c ($l) print -r ${(P)c} |