当字节存储在 Perl 中的不同变量中时,如何从其字节创建 Unicode 字符?

发布于 2024-08-02 03:01:58 字数 637 浏览 2 评论 0 原文

我正在尝试将 Unicode 字符的十六进制表示形式转换为它们所表示的字符。 以下示例运行良好:

#!/usr/bin/perl

use Encode qw( encode decode );
binmode(STDOUT, ':encoding(utf-8)');

my $encoded = encode('utf8', "\x{e382}\x{af}");
eval { $encoded = decode('utf8', $encoded, Encode::FB_CROAK); 1 }
or print("coaked\n");

print "$encoded\n";

但是十六进制数字存储在 3 个变量中。

因此,如果我用以下内容替换编码行:

my $encoded = encode('utf8', "\x{${byte1}${byte2}}\x{${byte3}}");

where

my $byte1 = "e3"; my $byte2 = "82"; my $byte3 = "af";

它会失败,因为它尝试立即评估 \x 并将 $ 符号和 { 视为字符。

有谁知道如何解决这个问题。

I am trying to Convert hex representations of Unicode characters to the characters they represent. The following example works fine:

#!/usr/bin/perl

use Encode qw( encode decode );
binmode(STDOUT, ':encoding(utf-8)');

my $encoded = encode('utf8', "\x{e382}\x{af}");
eval { $encoded = decode('utf8', $encoded, Encode::FB_CROAK); 1 }
or print("coaked\n");

print "$encoded\n";

However the hex digits are stored in 3 variables.

So if i replace the encode line with this:

my $encoded = encode('utf8', "\x{${byte1}${byte2}}\x{${byte3}}");

where

my $byte1 = "e3"; my $byte2 = "82"; my $byte3 = "af";

It fails as it tries to evaluate the \x immediately and sees the $ sign and { as characters.

Does anyone know how to get around this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

冰葑 2024-08-09 03:01:58

代替

my $encoded = 编码('utf8', "\x{${byte1}${byte2}}\x{${byte3}}"); 
  

您可以使用

my $encoded = encode('utf8', chr(hex($byte1 . $byte2)) . chr(hex($byte3)));

hex() 从十六进制转换,并且 chr() 返回给定代码点的 unicode 字符。

[编辑:]

与您的问题无关,但我注意到您在程序中混合了utf-8utf8。 我不知道这是否是一个拼写错误,但您应该意识到这些在 Perl 中不是同一件事:
utf-8 (带连字符,不区分大小写)是 UTF-8 标准所说的内容,而 utf8 (没有连字符,也不区分大小写)是 Perls 内部编码,其定义更为宽松(它允许不是有效 unicode 代码点的代码点)。 一般来说,您应该坚持使用 utf-8 (perlunifaq 有详细信息)。

Instead of

my $encoded = encode('utf8', "\x{${byte1}${byte2}}\x{${byte3}}");

You can use

my $encoded = encode('utf8', chr(hex($byte1 . $byte2)) . chr(hex($byte3)));

hex() converts from hexadecimal, and chr() returns the unicode character for a given code point.

[Edit:]

Not related to your question, but I noticed you mix utf-8 and utf8 in your program. I don't know if this is a typo, but you should be a ware that these are not the same things in Perl:
utf-8 (with hyphen, case insensitive) is what the UTF-8 standard says, whereas utf8 (no hyphen, also case insensitive) is Perls internal encoding, which is more loosely defined (it allows codepoints that are not valid unicode codepoints). In general, you should stick to utf-8 (perlunifaq has the details).

静赏你的温柔 2024-08-09 03:01:58

trendel的答案似乎不错,但是 Encode::Escape 提供了另一种选择解决方案:

use Encode::Escape::Unicode;

my $hex = '263a';
my $escaped = "\\x{" . $hex . "}\n";
print encode 'utf8', decode 'unicode-escape', $escaped;

trendel's answer seems pretty good, but Encode::Escape offers an alternative solution:

use Encode::Escape::Unicode;

my $hex = '263a';
my $escaped = "\\x{" . $hex . "}\n";
print encode 'utf8', decode 'unicode-escape', $escaped;
凉薄对峙 2024-08-09 03:01:58

首先,认真思考为什么最终会得到三个变量 $byte1、$byte2、$byte3,每个变量都保存一个字节的数据,作为十六进制的两个字符的字符串。 你的程序的这一部分看起来很困难,因为上面的设计决策很糟糕。 修正这个错误的决定,这部分代码就会自然而然地消失。

话虽这么说,我认为你想做的是:


my $byte1 = "e3"; my $byte2 = "82"; my $byte3 = "af";
my $str = chr(hex($byte1 . $byte2)) . chr(hex($byte3))

编码的东西是一个转移注意力的东西; 你不应该担心程序中间的编码,只有当你进行 IO 时才需要担心。

我在上面假设您想​​要得到一个两个字符串,U+E382 后跟 U+AF。 这就是你真正要求的。 但是,由于没有 U+E382,并且它位于私人使用区域的中间,因此这可能不是您真正想要的。 请尝试改写问题? 也许问一个更基本的问题,并描述您想要实现的目标,而不是您将如何尝试做到这一点?

First off, think hard about why you ended up with three variables, $byte1, $byte2, $byte3, each holding one byte's worth of data, as a two-character string, in hex. This part of your program seems hard because of a poor design decision further up. Fix that bad decision, and this part of the code will fall out naturally.

That being said, what you want to do, I think, is this:


my $byte1 = "e3"; my $byte2 = "82"; my $byte3 = "af";
my $str = chr(hex($byte1 . $byte2)) . chr(hex($byte3))

The encoding stuff is a red herring; you shouldn't be worrying about encodings in the middle of your program, only when you do IO.

I'm assuming in the above that you want to get out a two character string, U+E382 followed by U+AF. That's what you actually asked for. However, since there is no U+E382, since it's in the middle of the private use area, that's probably not what you actually wanted. Please try to reword the question? Perhaps ask a more basic question, and describe what you are trying to achieve, rather then how you are going about trying to do it?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文