2010-07-16 5 views
5

ich ganz neu bin zu Perl-Entwicklung, und ich möchte eine folgende Aufgabe auszuführen:Perl: mit regex hex-codierten Zeichenfolge in einem Array analysiert

Mein Skript hex-codierte Zeichenfolge als Befehlszeilen param empfängt . Dann muss ich diese Zeichenfolge decodieren und sie in die Ausgabedatei wie ein C++ - Array mit Initialisierung aus den angegebenen Daten schreiben. Zum Beispiel:

perl myscript.pl DEADBABEDEADBEEF und der Ausgang so etwas wie

const boost::array<char, 8> MyArray = { 0xDE, 0xAD, 0xBA, 0xBE, 0xDE, 0xAD, 0xBE, 0xEF };

Was ist der richtige Weg ist dies mit Perl Regex zu tun? Natürlich könnte ich es in einer Schleife mit Teilstrings durchführen, aber ich glaube, dass es elegantere Wege geben sollte.

BEARBEITEN: Die Eingabezeichenfolge hat eine feste Länge.

+1

Was ist Split/Karte auspacken? Wenn Sie nicht sicher sind, dass Ihre Eingabezeichenfolge eine feste Länge hat, bezweifle ich, dass regexp eine gute Wahl wäre. –

+0

Ja, in diesem Fall bin ich sicher, dass meine Eingabezeichenfolge eine feste Länge haben wird. Ich werde die Frage aktualisieren. – Haspemulator

Antwort

6

Try this:

my $hex = "DEADBABEDEADBEEF"; 
my @a = map "0x$_", $hex =~ /(..)/g; 

Wie es funktioniert:

Zuerst $hex =~ /(..)/g in Listenkontext alle 2-Zeichen-Strings erfasst (die /g Markierungsmittel globale Übereinstimmung). Dann nimmt map() die Liste und wandelt sie in eine andere um, wobei der Ausdruck "0x$_" für jedes Element der ersten Liste verwendet wird ($_ ist hier ein Alias ​​für das Element).

Siehe auch perldoc -f map.

+0

Danke, dein Skript funktioniert. Aber könnten Sie mir bitte die Details erklären? Was ist dort passiert und was ist das "," (Komma) zwischen der Operation? Wie gesagt, ich bin bei Perl ziemlich neu. :) – Haspemulator

+0

@ Haspemulator: Das ist eine ziemlich große Aufgabe. Versuchen Sie 'perldoc -f map', um die Dokumentation für die Kartenfunktion zu erhalten, und' perldoc perlre', um die Dokumentation für reguläre Ausdrücke zu erhalten. –

+0

@Kinopiko, danke für den Kommentar, es ist jetzt klarer. – Haspemulator

5

Wie wäre es damit:

my $input = $ARGV[0]; 
die "Fouled up input" unless $input =~ /^(?:[0-9A-F]{2})+$/i; 
my $bytes = length ($input)/2; 
print "const boost::array<char, $bytes> MyArray = {"; 
while ($input =~ s/([0-9A-F]{2})//i) { 
    # print $input # to see how this works, see comment. 
    print "0x$1, "; 
} 
print "};\n"; 
+0

Danke, Ihre Antwort ist richtig. Aber die zweite Antwort ist auch richtig. Ich bin mir nicht sicher, für wen ich wählen sollte. :) Und ich habe eine Frage zu Ihrem Code: Warum in Anweisung '$ input = ~ s/([0-9A-F] {2}) //' Sie links zweiten Argument von s /// leer? Was bedeutet das in diesem Zusammenhang? – Haspemulator

+0

Es löscht nur die ersten zwei Zeichen jedes Mal. Setzen Sie einen 'print $ input' in die Schleife und Sie werden sehen, wie es funktioniert. –

+0

@Kinopiko, ok, ich habe es. Vielen Dank. – Haspemulator

4

Wie wäre es mit Auspacken?

print join ",", unpack("(A2)*", "DEADBABEDEADBEEF"); 

Korrektur - Sie eine Karte benötigen würde jedes Element Präfix, das kehrt mit einem "0x"

print join ",", map { '0x' . $_ } unpack("(A2)*", "DEADBABEDEADBEEF");