2016-06-10 4 views
3

Ich scrape eine Webseite und extrahiere einen bestimmten Abschnitt daraus. Dieser Abschnitt enthält Anführungszeichen (, Zeichen 146). Ich versuche, meine extrahierten Daten in eine Textdatei zu drucken, aber es gibt mir ’ anstelle des Anführungsstrichs. Ich habe folgendes versucht:Codierungsmodul und Anführungszeichen

  • $content =~ s/’/'/g;
  • my $invComma = chr 146; $content =~ s/$invComma/'/g;
  • $content =~ s/\x{0092}/'/g;

Nichts davon gearbeitet hat. Ich kann nicht decode('UTF-8', $content), weil es breite Zeichen hat. Wenn ich versuche, encode('UTF-8', $content) die ’ ändert sich stattdessen zu ’. Ich habe auch bereits use utf8 versucht, ohne Wirkung.

Ich weiß, dass mein Textdateibetrachter Anführungszeichen anzeigen kann, weil ich einen zu einer Testdatei ausgedruckt und geöffnet habe. Das Problem ist daher in meinem Skript.

Was mache ich falsch, und wie repariere ich es?

UPDATE: Ich bin in der Lage $content =~ s/’/'/g, es zu tun mit einem einfachen Apostroph zu ersetzen, aber ich weiß immer noch nicht, warum es nicht anders geht. Ich möchte auch eine Lösung, die das Problem tatsächlich löst, anstatt nur eines der Symptome zu lösen.

UPDATE 2: Ich habe von hobbs informiert worden, dass der Charakter tatsächlich U+2019 RIGHT SINGLE QUOTATION MARK ist und änderte meine regex chr 0x2019 zu verwenden, die jetzt funktioniert.

+1

Wie auch immer Sie den Inhalt der Webseite abrufen, es interpretiert die Codierung falsch - aber Sie haben diesen Teil des Codes nicht in Ihre Frage aufgenommen. – hobbs

+0

Ich verwende LWP :: Simple-Methode get (_URL_). Was würdest du stattdessen empfehlen? – Lilith

+0

Sind Sie sicher, dass das _invertierte Komma_ 146 ist? Ich kopiere es einfach von meinem OP in meinen Editor, speichere es, habe "hexdump -C" und habe "e2 80 99". – PerlDuck

Antwort

1

Das Problem war nicht in meinem Skript, es war in meinem Editor. Das Skript funktioniert ordnungsgemäß und die Frage basiert auf falschen Vorwänden. Ich habe gVim unter Windows verwendet, was nicht gut mit Unicode funktioniert. Mein Skript hat den Inhalt korrekt dekodiert, aber als ich die Ausgabedatei in gVim geöffnet habe, hat es den Text verstümmelt und falsch dargestellt. Meine Versuche, reguläre Ausdrücke zu verwenden, um die Zeichen zu ändern, scheiterten, weil ich den falschen Codepoint verwendete - es war nicht 0x92, es war 0x2019. Dies war ein weiterer Fehler von gVim. Danke an hobbs und ikegami für die Hilfe, das herauszufinden.

5

Das Zeichen, das Sie ersetzen möchten, ist nur 0x92/146 in der Windows-1252-Codierung. Perl verwendet Unicode, wobei das Zeichen U+2019 RIGHT SINGLE QUOTATION MARK, alias "\x{2019}", chr(0x2019) oder chr(8217) ist.

+0

Also sollte ich nach dem richtigen _unicode_ Codepoint online suchen und die Ersetzungen auf diese Weise tun? Kann ich stattdessen das Encodemodul für meine Eingabe verwenden? Wenn das so ist, wie? – Lilith

+0

@Lilith Sie benötigen das Encode-Modul nicht, Ihr Eingang wurde bereits korrekt dekodiert (mit dem Encode-Modul) von LWP. LWP :: Simple verwendet die Methode decoded_content von HTTP :: Response. – hobbs

+0

Also, wie kann ich mein Skript korrekt drucken? Ich markierte die Ausgabedatei als utf8 mit IO :: All und druckte dann die Ausgabe direkt. Es erschien stattdessen als "â €".Ich _could_ nur Ersatz für die drei Zeichen hinzufügen (öffnen/schließen doppelte Anführungszeichen und richtige einfache Anführungszeichen), aber ich würde lieber das Problem als das Symptom lösen. – Lilith

4

Beginnen Sie herauszufinden, was $content enthält. Sie können die folgenden Befehle verwenden:

use Data::Dumper; 
local $Data::Dumper::Useqq = 1; 
warn(Dumper($content)); 

Wenn Sie die folgende erhalten, $content

$VAR1 = "...\x{2019}..."; 

Jede der folgenden decodiert wird funktionieren.

use utf8; # Source code is encoded using UTF-8. 
$content =~ s/’/'/g; 

$content =~ s/\x{2019}/'/g; 

$content =~ s/\N{U+2019}/'/g; 

$content =~ s/\N{RIGHT SINGLE QUOTATION MARK}/'/g; 

Wenn Sie Folgendes erhalten, wird $content mit UTF-8 codiert.

$VAR1 = "...\342\200\231..."; 

Start, um den Wert von $content durch Decodieren einer der folgenden verwendet:

utf8::decode($content) or die; 

use Encode qw(decode_utf8); 
$content = decode_utf8($content); 

Dann jeder der Lösungen für die decodierten Inhalt (oben) verwenden.


Wenn Sie die folgende erhalten, $content codiert wird cp1252 verwenden.

$VAR1 = "...\222..."; 

Beginnen Sie mit der Decodierung des Werts $content.

use Encode qw(decode); 
$content = decode("cp1252", $content); 

Verwenden Sie dann eine der Lösungen für decodierten Inhalt (oben).


By the way, ’ ist, was die UTF-8-Codierung von (E2 80 99) wie als cp1252 wenn dekodiert aussehen würde.

Verwandte Themen