将字符串中的多个Unicode转换为字符

时间:2013-08-28 12:02:40

标签: regex string perl unicode

问题 - 我有一个字符串,比如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

3 个答案:

答案 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///ege表示将替换文本视为要执行的代码。 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;
相关问题