Wie kann ich bereinigen ungültige UTF-8 in Perl?
Mein Perl-Programm nimmt text aus einer Datei als Eingabe, wickelt es in einigen XML-und gibt es auf STDOUT aus. Der Eingang ist nominell UTF-8, aber manchmal hat junk eingefügt. Ich müssen zu bereinigen, die Ausgabe, dass kein Ungültiger UTF-8-Oktetten emittiert werden, da sonst die nachgeschalteten Verbraucher (Sphinx) wird sprengen.
Zumindest würde ich gerne wissen wenn die Daten ungültig sind, so kann ich vermeiden, weitergeben; im Idealfall konnte ich entfernen, nur der säumige bytes. Jedoch, um alle fatalisms finde ich nicht so Recht, mich dort mit perl 5.12 (FWIW, use v5.12; use warnings qw( FATAL utf8 );
ist in-Effekt).
Bin ich speziell Probleme mit der Reihenfolge "\xFE\xBF\xBE"
. Wenn ich eine Datei erstellen, die nur diese drei bytes (perl -e 'print "\xEF\xBF\xBE"' > bad.txt
), versuchen, Lesen Sie die Datei mit dem Modus :encoding(UTF-8)
Fehler mit utf8 "\xFFFE" does not map to Unicode
, aber nur unter 5.14.0. 5.12.3 und früher sind gut zu Lesen und später zu schreiben, dass die Sequenz. Ich bin mir nicht sicher, wo es immer die \xFFFE
(illegales reverse-BOM) aus, aber zumindest eine Beschwerde ist im Einklang mit der Sphinx.
Leider decode_utf8("\xEF\xBF\xBE", 1)
verursacht keine Fehler unter 5.12 oder 5.14. Ich würde es vorziehen, eine Nachweismethode, die nicht verlangen, eine codierte I/O-Schicht, wie das wird nur lassen Sie mich mit einer Fehlermeldung und keine Möglichkeit zu desinfizieren, die raw-Bytes.
Ich bin sicher, es gibt mehr Sequenzen, die ich ansprechen müssen, sondern einfach die Handhabung dieser wäre ein Anfang. Also meine Fragen sind: kann ich zuverlässig erkennen, diese Art von problem, die Daten mit einem perl-bevor 5.14? Was die substitution von routine kann in der Regel bereinigen, fast-UTF-8 in die strengen UTF-8?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Lesen Sie die UTF-8 vs. utf-8 vs. UTF-8-Abschnitt der Codieren docs.
Zusammenfassen, Perl hat zwei verschiedene UTF-8-Codierungen. Seine native encoding heißt
utf8
, und im Grunde können alle codepoint, unabhängig davon, was im Unicode-standard sagt über die codepoint.Den anderen encoding heißt
utf-8
(ein.k.ein.utf-8-strict
). Dadurch wird nur die codepoints, die aufgeführt sind, als legal für den Austausch durch den Unicode-standard."\xEF\xBF\xBE"
, wenn Sie interpretiert wird als UTF-8 dekodiert, um die codepoint U+FFFE. Aber das ist nicht legal für den Austausch nach Unicode, so dass Programme, die streng über solche Dinge beschweren.Anstatt
decode_utf8
(was nutzt das laxutf8
Codierung), verwenden Siedecode
mit derutf-8
Codierung. Und Lesen Sie die Umgang Mit Fehlerhaften Daten Abschnitt sehen Sie die verschiedenen Möglichkeiten, die Sie verarbeiten kann, oder beschweren sich über Probleme.Update: Es scheint, dass einige Versionen von Perl beschweren Sie sich nicht über die U+FFFE, auch wenn das
utf-8-strict
Codierung. Dies scheint ein Fehler zu sein. Sie können nur zu bauen, eine Liste der codepoints, die Sphinx beschwert, und filtern Sie diese manuell (z.B. mittr
).tr[\x{9}\x{A}\x{D}\x{20}-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}][]cd
sieht, wie es funktionieren wird, zumindest in 5.14. Einen ganz anderen Vorschlag, den ich gefunden, der sich nicht auf eine neue perl überhaupt:iconv -c --from UTF-8 --to UTF-8
.Haben Sie einen utf8-string enthält einige ungültige utf8...
Diese ersetzt mit einer Standard - "bad char".