2

问题——我有一个字符串,比如Buna$002C_TexasBuna$002C_Texas' 和 where$后面是 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", line$str被插值,而不是它的值。因此\x{002C},Perl 不会对其进行插值。

有没有办法强制 Perl 让它也插入内容$str

或者

有没有另一种方法来实现这一目标?我不想取出每个 Unicode,然后将其打包使用pack "U4",0x002C,然后再将其替换回去。但是一行中的某些内容(例如以下不成功的尝试)是可以的。

$str =~ s/\$(.{4})/pack("U4",$1)/g;

我知道以上是错误的;但我可以做上面的事情吗?

对于输入字符串$str = 'Buna$002C_TexasBuna$002C_Texas',所需的输出是Buna,_TexasBuna,_Texas.

4

3 回答 3

7

这给出了预期的结果:

use strict;
use warnings;
use feature 'say';

my $str = 'Buna$002C_TexasBuna$002C_Texas';

$str =~s/\$(.{4})/chr(hex($1))/eg;

say $str;

主要有趣的项目是ein s///eg。将e替换文本视为要执行的代码的方法。将hex()一串十六进制字符转换为数字。将chr()数字转换为字符。替换行最好如下编写,以避免尝试将美元转换为非十六进制字符。

$str =~s/\$([0-9a-f]{4})/chr(hex($1))/egi;
于 2013-08-28T12:37:29.923 回答
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;
于 2013-08-28T13:28:42.540 回答
1

您可以执行诸如pack替换字符串中的语句,您只需要使用e正则表达式修饰符。

或者你可以这样做

$str =~s/\$(.{4})/"@{[pack("U4",$1)]}/g;

如果这两个选项不起作用,请告诉我,查看这个Stackoverflow 问题以获取更多信息。

于 2013-08-28T12:37:18.657 回答