\ x不在替换内部工作

mkH*_*Hun 4 regex unicode perl

我正在尝试解码unicode字符.所以我只是\x{}在正则表达式替换中尝试了十六进制转义序列e

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;
Run Code Online (Sandbox Code Playgroud)

我正在尝试替换所有unicode角色.

我的预期输出是:

https://someurl/call.pl?id=15967737&locale=en-GB&mkhun=ccce
Run Code Online (Sandbox Code Playgroud)

下面提到的print语句给出了预期的输出.然而,正则表达式似乎无法正常工作.

print "\x{0026}";
Run Code Online (Sandbox Code Playgroud)

Håk*_*and 7

问题s/\\u(.{4})/"\x{$1}"/e\x{$1}在编译时评估反斜杠转义,它给出一个NULL字节:

$ perl -E 'printf "%vX\n", "\x{$1}"'
0
Run Code Online (Sandbox Code Playgroud)

如果我们在x(s/\\u(.{4})/"\\x{$1}"/ge)前面转义反斜杠,我们得到一个带有文字转义序列的字符串,但仍然不是所需的unicode字符:

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

输出现在是:

\x{0026}
Run Code Online (Sandbox Code Playgroud)

通过一个小的修改,您可以生成"\x{0026}",也就是Perl代码,您可以编译并执行以生成所需的值.要做到这一点,你需要参与eval(EXPR).

$kv =~ s/\\u(.{4})/ my $s = eval(qq{"\\x{$1}"}); die $@ if $@; $s /ge;
Run Code Online (Sandbox Code Playgroud)

这可以缩短为

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

但是,更好的解决方案是使用以下方法:

$kv =~ s/\\u(.{4})/chr hex $1/ge;
Run Code Online (Sandbox Code Playgroud)