问题 - 我有一个字符串,比如Buna$002C_TexasBuna$002C_Texas
',其中$
后跟Unicode。我想用它们各自的Unicode字符表示替换这些Unicode。
在Perl中,如果任何Unicode的格式为“\x{002C}
,那么它将被转换为相应的Unicode字符。下面是示例代码。
#!/usr/bin/perl
my $string = "Hello \x{263A}!\n";
@arr= split //,$string;
print "@arr";
我正在处理一个包含1000万条记录的文件。所以我在标量变量中有这些字符串。要做到与上面相同,我将$4_digit_unicode
替换为\x{4_digit_unicode}
,如下所示。
$str = 'Buna$002C_TexasBuna$002C_Texas';
$str =~s/\$(.{4})/\\x\{$1\}/g;
$str = "$str"
它给了我
Buna\x{002C}_TexasBuna\x{002C}_Texas
这是因为在$str = "$str"
处,正在插入行$str
,而不是其值。因此Perl不会插入\x{002C}
。
有没有办法强制Perl,以便它也会插入$str
的内容?
OR
还有其他方法可以实现吗?我不想取出每个Unicodes,然后使用pack "U4",0x002C
打包,然后将其替换回来。但是一行中的某些内容(如下面的不成功尝试)是可以的。
$str =~ s/\$(.{4})/pack("U4",$1)/g;
我知道上面的错误;但我可以做上面这样的事吗?
对于输入字符串$str = 'Buna$002C_TexasBuna$002C_Texas'
,所需的输出为Buna,_TexasBuna,_Texas
。
答案 0 :(得分:6)
这给出了期望的结果:
use strict;
use warnings;
use feature 'say';
my $str = 'Buna$002C_TexasBuna$002C_Texas';
$str =~s/\$(.{4})/chr(hex($1))/eg;
say $str;
主要有趣的项目是e
中的s///eg
。 e
表示将替换文本视为要执行的代码。 hex()
将一串十六进制字符转换为数字。 chr()
将数字转换为字符。替换行可能更好地编写如下,以避免尝试转换美元后跟非十六进制字符。
$str =~s/\$([0-9a-f]{4})/chr(hex($1))/egi;
答案 1 :(得分:1)
您可以在替换字符串中执行pack
等语句,只需使用e
正则表达式修饰符。
或者你可以这样做
$str =~s/\$(.{4})/"@{[pack("U4",$1)]}/g;
如果这两个选项不起作用,请告诉我们,请查看此Stackoverflow question以获取更多信息。
答案 2 :(得分:1)
"\x{263A}"
(包含引号)是一个字符串文字,一段代码,当评估时会产生一个包含唯一字符263A
的字符串>由解释器(作为传递给perl
的脚本的一部分进行评估)。
"\\x\{$1\}"
(包含引号)会生成一个由\
,x
,{
组成的字符串,$1
的内容,和}
。
后者是您正在制作的字符串。您似乎正在尝试生成Perl代码,但它不是有效的Perl代码 - 它缺少引号 - 并且您永远不会由perl
解释代码。
$str =~ s/\$(.{4})/\\x\{$1\}/g;
是
的缩写 $str =~ s/\$(.{4})/ "\\x\{$1\}" /eg;
与
完全不同 $str =~ s/\$(.{4})/ "\x{263A}" /eg;
看起来你要采取以下措施:
$str =~ s/\$(.{4})/ eval qq{"\\x\{$1\}"} /eg;
但是有更简单的方法可以产生所需的字符串,例如
$str =~ s/\$(.{4})/ pack "U4", $1 /eg;
或更好,
$str =~ s/\$(.{4})/ chr hex $1 /eg;