2016-10-12 1 views
4

Ich versuche, die Unicode-Zeichen zu dekodieren. Also habe ich versucht, einfach die hexadezimale Escape-Sequenz \x{} in der regex Substitution e x funktioniert nicht innerhalb der Substitution

use LWP::Simple; 
my $k = get("url"); 

my ($kv) =map{/js_call\(\\"(.+?)\\"\)/} $k; 

#now $kv data is https://someurl/call.pl?id=15967737\u0026locale=en-GB\u0026mkhun=ccce 

$kv=~s/\\u(.{4})/"\x{$1}"/eg; 

ich Ersatz der alle Unicode-Zeichen bin versucht.

Meine erwartete Ausgabe ist:

https://someurl/call.pl?id=15967737&locale=en-GB&mkhun=ccce 

Im Folgenden genannten print Anweisung, um die erwartete Ausgabe gibt. Der Regex scheint jedoch nicht richtig zu funktionieren.

print "\x{0026}"; 

Antwort

7

Das Problem mit s/\\u(.{4})/"\x{$1}"/e ist, dass der Backslash \x{$1} wird bei der Kompilierung ausgewertet, die eine NULL-Byte gibt:

$ perl -E 'printf "%vX\n", "\x{$1}"' 
0 

Wenn wir den umgekehrten Schrägstrich vor x (s/\\u(.{4})/"\\x{$1}"/ge) entkommen bekommen wir einen String mit literal Escape-Sequenzen, aber immer noch nicht das gewünschte Unicode-Zeichen:

use feature qw(say); 
$kv = '\u0026'; 
$kv =~ s/\\u(.{4})/"\\x{$1}"/ge; 
say $kv; 

der Ausgang ist nun:

\x{0026} 

Mit einer kleinen Änderung können Sie stattdessen "\x{0026}" produzieren, das ist Perl-Code, den Sie kompilieren und ausführen können, um den gewünschten Wert zu erzeugen. Um dies zu tun, müssen Sie eval(EXPR) involvieren.

$kv =~ s/\\u(.{4})/ my $s = eval(qq{"\\x{$1}"}); die [email protected] if [email protected]; $s /ge; 

Dies kann

$kv =~ s/\\u(.{4})/ qq{"\\x{$1}"} /gee; 

Howver, eine weit bessere Lösung zu

verkürzt werden soll, die folgende verwenden:

$kv =~ s/\\u(.{4})/chr hex $1/ge; 
+0

@ikegami Danke für die Bearbeitung! –

2

Wenn Sie use warnings aktivieren Sie werden sehen, dass die $1 buchstäblich ausgewertet wird, bevor die Rückreferenzierung interpoliert wird.

$kv =~ s/\\u(.{4})/ sprintf("\"\\x{%s}\"", $1) /eeg; 

Art von Arbeiten, aber es ist schrecklich hässlich. Ich habe versucht, es zu vereinfachen, aber die verschiedenen Ideen, die ich probierte, brachten mich immer wieder zu "Illegal hexadecimal digit $ 'ignored" Warnungen.

2

Kann dies auch können Sie versuchen:

$kv=~s/\\u([[:xdigit:]]{1,5})/chr(eval("0x$1"))/egis;

Dank.

Verwandte Themen