2 Stimmen

Wie kann ich korrekte Nicht-ASCII-Befehlszeilenargumente in ActiveState Perl erhalten?

Ausführen des folgenden Befehls

perl -e "for (my $i = 0; $i < length($ARGV[0]); $i++) {print ord(substr($ARGV[0], $i, 1)), qq{\n}; }" 

in einem Windows 7 cmd-Fenster mit ActiveState Perl v5.14.2 führt zu folgendem Ergebnis:

97
223
63
100
101
63

Die obigen Werte sind unsinnig und entsprechen keiner bekannten Kodierung, so dass der Versuch, sie mit dem in Wie kann ich Befehlszeilenargumente in Perl als UTF-8 behandeln? ist nicht hilfreich. Das Ändern der aktiven Code-Seite des Befehlsfensters ändert nichts an den Ergebnissen.

3voto

ikegami Punkte 340842

Ihr System verwendet, wie alle mir bekannten Windows-Systeme, standardmäßig die 1252 ANSI-Codepage, so dass Sie versuchen könnten, die

use Encode qw( decode );
@ARGV = map { decode('cp1252', $_) } @ARGV;

Beachten Sie, dass cp1252 nicht alle diese Zeichen darstellen kann, weshalb die Konsole und damit Perl tatsächlich

  • a 97
  • ß 223
  • ? 63
  • d 100
  • e 101
  • ? 63

Es gibt eine "Wide"-Schnittstelle, über die (fast) jeder Unicode-Codepunkt an ein Programm übergeben werden kann, aber

  1. Die breite Schnittstelle wird nicht verwendet, wenn Sie einen Befehl an der Eingabeaufforderung eingeben.
  2. Perl verwendet die ANSI-Schnittstelle, um die Parameter zu holen. Selbst wenn Sie Perl mit der Wide-Schnittstelle starten würden, würden die Parameter auf ANSI heruntergestuft werden, wenn Perl sie holt.

Tut mir leid, aber das ist eine Situation, in der Sie nicht können. Sie brauchen einen anderen Ansatz. Diomidis Spinellis schlägt vor, die ANSI-Codepage Ihres Systems unter Win7 wie folgt zu ändern:

  1. Bedienfeld
  2. Region und Sprache
  3. Verwaltung
  4. Sprache für Nicht-Unicode-Programme
  5. Setzen Sie die Aktuelle Sprache für Nicht-Unicode-Programme auf die Sprache, die mit den spezifischen Zeichen verbunden ist (in Ihrem Fall Griechisch).

An diesem Punkt würden Sie die Kodierung der ANSI-Codepage verwenden, die mit der neu ausgewählten Kodierung verbunden ist, anstatt cp1252 ( cp1253 für Griechisch).

use Encode qw( decode );
@ARGV = map { decode('cp1253', $_) } @ARGV;

Beachten Sie, dass die Verwendung von chcp um die im Konsolenfenster verwendete Codepage zu ändern, hat keinen Einfluss auf die Codepage, in der Perl seine Argumente empfängt, die immer eine ANSI-Codepage ist. Siehe die Beispiele unten (cp737 ist die griechische OEM-Code-Seite und cp1253 ist das griechische ANSI-Code-Seite . Sie finden die mit 37 und M7 gekennzeichneten Kodierungen in dieses Dokument .)

C:\\>chcp 737
Active code page: 737

C:\\>echo  | od -t x1
0000000 98 99 9a 9b 9c 9d 20 0d 0a

C:\\>perl -e "print map sprintf('%x ', ord($\_)), split(//, $ARGV\[0\])" 
e1 e2 e3 e4 e5 e6

C:\\>chcp 1253
Active code page: 1253

C:\\>echo  | od -t x1
0000000 e1 e2 e3 e4 e5 e6 20 0d 0a

C:\\>perl -e "print map sprintf('%x ', ord($\_)), split(//, $ARGV\[0\])" 
e1 e2 e3 e4 e5 e6

0voto

MisterEd Punkte 1685

Das hat bei mir funktioniert (unter OS-X, sollte aber portabel sein):

echo   |perl -CI -e "chomp($in=<STDIN>);for (my $i = 0; $i < length($in); $i++) {print ord(substr($in, $i, 1)), qq{\n}; }"

Das war für STDIN; für ARGV:

perl -CA -e "for (my $i = 0; $i < length($ARGV[0]); $i++) {print ord(substr($ARGV[0], $i, 1)), qq{\n}; }" 

Siehe die -C Option in perlrun: http://perldoc.perl.org/perlrun.html#Command-Switches

0voto

MisterEd Punkte 1685

Wenn ich die Zeichen in eine Datei (von OS-X) einfüge und sie auf ein Windows-System kopiere (als file.txt ), dann ausführen:

perl -CI -e "chomp($_=<STDIN>); map{print ord, qq{\n}} split(//)" < file.txt

Dann bekomme ich das Erwartete:

946
947
948
949
950

Aber wenn ich den Inhalt von file.txt in die Befehlszeile eingeben, erhalte ich Kauderwelsch.

Wie @ikegami sagte, glaube ich nicht, dass es möglich ist, von der Kommandozeile aus zu tun, da Sie nicht über ein UTF-8 Gebietsschema verfügen.

0voto

asdf000 Punkte 79

Sie könnten versuchen https://metacpan.org/pod/Win32::Unicode::Native . Es sollte alles enthalten, was Sie brauchen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X