【问题标题】:UTF-8 to UTF-16 in perlperl 中的 UTF-8 到 UTF-16
【发布时间】:2021-01-06 02:16:48
【问题描述】:

我想将 UTF-8 字符串转换为十六进制表示法的 UTF-16BE 字符串。

例如,假设我有字符串“C'est-à-dire que ça c'est l'été”。

say sprintf("%vX", $string);  # 43.27.65.73.74.2D.E0.2D...

应该转换成

00430027006500730074002d00e0002d...

我正在使用

use Encode qw(decode encode); 
use feature 'unicode_strings' ;

到目前为止,我还没有成功使用“encode”和“unpack”。

正确的方法是什么?

【问题讨论】:

  • 这与your question on superuser.com 完全相同的问题。虽然我本人建议您将其发布在 stackoverflow.com 上,但我明确表示您应该:"... 提供您迄今为止尝试过的内容,而不是仅仅说它不成功并期望其他人提供您问题的完整代码。”。因此,请编辑您的问题以提供您迄今为止尝试过的内容。

标签: perl unicode


【解决方案1】:

使用sprintford

#!/usr/bin/env perl
use warnings;
use strict;
use utf8;
use feature qw/say/;

my $string = "C'est-à-dire que ça c'est l'été.";

say join("", map { sprintf "%04x", ord $_ } split(//, $string));

输出

00430027006500730074002d00e0002d00640069007200650020007100750065002000e700610020006300270065007300740020006c002700e9007400e9002e

【讨论】:

  • 这适用于基本的多语言平面,但会失败。
  • “sprintf and ord”解决方案在本案例中按预期工作。当然,我们还要考虑 UTF-16 的局限性。当字符的长度必须恒定时,更通用的解决方案是使用 UTF-32。
【解决方案2】:

首先,您的字符串没有像您声称的那样使用 UTF-8 编码。使用 UTF-8 编码的 "à" (U+E0) 将是 C3 A0,但您有 E0。我猜你已经解码了文本,也就是一串 Unicode 代码点。 (那将是一件好事。您通常希望使用解码的文本。)

要将解码后的文本转换为 UTF-16be,您可以使用

use Encode qw( encode );
my $s_utf16be = encode("UTF-16be", $s_ucp);
# "\x00\x43\x00\x27\x00\x65\x00\x73\x00\x74\x00\x2d\x00\xe0\x00\x2d..."

但您不想要 UTF-16be;你想要字符串的 UTF-16be 编码的十六进制表示。

my $s_utf16be_hex = unpack("H*", $s_utf16be);
# "00430027006500730074002d00e0002d..."

【讨论】:

  • 从您对另一个答案的评论中,我认为您有一串 UCP aka 解码文本而不是 UTF-8。
  • "说 sprintf("%vX", $string) ;"结果为 43.27.65.73.74.2D.E0.2D.64.69.72.65.20.71.75.65.20.E7.61.20.63.27.65.73.74.20.6C.27.E9.74.E9.2E 但两种解决方案都没有给出预期的结果。
  • 啊,我以为您想要字符串的 UTF-16 编码,但另一个问题的阅读表明您想要字符串的 UTF-16 编码的 ASCII 编码十六进制表示。我已经调整了答案。
猜你喜欢
  • 2012-08-18
  • 2020-01-29
  • 2021-01-30
  • 2011-01-11
  • 2012-10-08
  • 1970-01-01
  • 2016-05-31
  • 2015-09-21
  • 2015-12-06
相关资源
最近更新 更多