2014-06-24 5 views
12

Ich habe das folgende Problem: Ich lese von einer UTF-8-Textdatei (und ich erzähle Perl, dass ich das tue durch ": encoding (utf-8)").Entfernen Sie Stückliste von String mit Perl

Die Datei sieht wie folgt in einem Hex-Viewer: EF BB BF 43 6F 6E 66 65 72 65 6E 63 65

Dies führt zu "∩╗┐Conference", wenn gedruckt. Ich verstehe den "weiten Charakter", vor dem ich gewarnt bin, ist die Stückliste. Ich will es loswerden (nicht wegen der Warnung, sondern weil es einen String-Vergleich vermasselt, den ich später unternehme).

Also versuchte ich es mit dem folgenden Code zu entfernen, aber ich kläglich:

$ line = ~ s/^ \ xEF \ xBB \ xBF //;

Kann mir jemand erklären, wie ich die UTF-8-Stückliste aus einer Zeichenfolge entfernen kann, die ich durch Lesen der ersten Zeile der UTF-8-Datei erhalten habe?

Danke!

+0

Solange Sie die Ausgabecodierung haben richtig eingestellt sollte es nicht nötig sein, um die BOM zu entfernen, da eine Null-Breite Raum haben keine Auswirkung auf das Ergebnis – Borodin

Antwort

9

EF BB BF ist die UTF-8-Kodierung der Stückliste, aber Sie haben sie dekodiert, also müssen Sie nach ihrer entschlüsselten Form suchen. Die Stückliste ist ein ZERO WIDTH NO-BREAK SPACE (U + FEFF) am Anfang einer Datei verwendet, so dass eine der folgenden Bedingungen tun:

s/^\x{FEFF}//; 
s/^\N{U+FEFF}//; 
s/^\N{ZERO WIDTH NO-BREAK SPACE}//; 
s/^\N{BOM}//; # Convenient alias 

Ich verstehe die „Wide-Zeichen "Worüber ich gewarnt werde, ist die BOM. Ich will davon

Sie bekommen breiten Charakter loszuwerden, weil Sie eine :encoding Schicht auf der Ausgabedatei Griff hinzuzufügen vergessen. Das Folgende fügt STDIN, STDOUT, STDERR :encoding(UTF-8) hinzu und macht es zum Standardwert für open().

use open ':std', ':encoding(UTF-8)'; 
+0

, um die Kurzschrift zu verwenden, musste ich hinzufügen verwenden charnames ': full'; – user1769925

+0

Ich denke, 5,12 ist für '\ N {...}' Ich denke, 5,14 wird für '\ N {BOM}' benötigt. 'charnames verwenden ': full';' wird vor 5.16 benötigt. – ikegami

+0

@ user1769925: Beachten Sie, dass das Problem darin besteht, dass Sie die Daten aus der Datei * dekodiert haben (wegen Ihres ': encoding (utf-8)' open Modus), also das erste * Zeichen * der Eingabezeichenfolge ist Unicode 'U + FEFF', aber Sie verwenden rohe UTF-8-codierte Datenbytes in Ihrer Ersetzung – Borodin

3

die BOM zu entschärfen, haben Sie es nicht 3 Zeichen wissen, ist es 1 in UTF (U + FEFF):

s/^\x{FEFF}//; 
+0

le upvote für die Bezugnahme darauf, als ob es ein Sprengstoff wäre. –

2

Wenn Sie die Datei mit File::BOM öffnen, entfernen Sie die Stückliste für Sie.

use File::BOM; 

open_bom(my $fh, $path, ':utf8') 
0

Im Idealfall sollte Ihr Dateihandle dies für Sie automatisch tun. Aber wenn Sie nicht in einer idealen Situation sind, arbeitete für mich:

use Encode; 

my $value = decode('UTF-8', $originalvalue); 
$value =~ s/\N{U+FEFF}//;