我正在尝试解码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;
我正在尝试替换所有unicode角色。
我的预期输出是:
https://someurl/call.pl?id=15967737&locale=en-GB&mkhun=ccce
下面提到的print
语句给出了预期的输出。然而,正则表达式似乎无法正常工作。
print "\x{0026}";
答案 0 :(得分:7)
s/\\u(.{4})/"\x{$1}"/e
的问题是在编译时计算反斜杠转义\x{$1}
,这给出了一个NULL字节:
$ perl -E 'printf "%vX\n", "\x{$1}"'
0
如果我们在x
(s/\\u(.{4})/"\\x{$1}"/ge
)前面转义反斜杠,我们会得到一个包含文字转义序列的字符串,但仍然不是所需的unicode字符:
use feature qw(say);
$kv = '\u0026';
$kv =~ s/\\u(.{4})/"\\x{$1}"/ge;
say $kv;
输出现在是:
\x{0026}
通过一个小的修改,您可以生成"\x{0026}"
,这是您可以编译和执行的Perl代码,以生成所需的值。为此,您需要参与eval(EXPR)
。
$kv =~ s/\\u(.{4})/ my $s = eval(qq{"\\x{$1}"}); die $@ if $@; $s /ge;
这可以缩短为
$kv =~ s/\\u(.{4})/ qq{"\\x{$1}"} /gee;
然而,更好的解决方案是使用以下内容:
$kv =~ s/\\u(.{4})/chr hex $1/ge;
答案 1 :(得分:2)
如果您启用use warnings
,您会看到$1
在反向引用进行插值之前按字面意义进行评估。
$kv =~ s/\\u(.{4})/ sprintf("\"\\x{%s}\"", $1) /eeg;
有点作品,但它很丑陋。我一直试图简化它,但我尝试过的各种想法总让我回到了非法的十六进制数字' $'忽略"警告。
答案 2 :(得分:2)
也许你可以试试这个:
$kv=~s/\\u([[:xdigit:]]{1,5})/chr(eval("0x$1"))/egis;
感谢。