【问题标题】:Reading unicode chars on the byte level在字节级别读取 unicode 字符
【发布时间】:2012-12-17 21:48:59
【问题描述】:

假设我想检测 unicode 字符并使用 \u 表示法对它们进行编码。如果我必须使用字节数组,是否可以遵循简单的规则来检测属于单个字符的字节组?

我指的是需要为仅 ASCII 接收器编码的 UTF-8 字节。目前,非 ASCII 可打印字符被剥离。 s/[^\x20-\x7e\r\n\t]//g.

我想改进此功能以编写\u0000 表示法。

【问题讨论】:

  • \u 与 UTF8 没有任何关系。
  • @SLaks,查看我的编辑。如果我有任何不清楚的地方,请告诉我。

标签: perl unicode byte


【解决方案1】:

你需要有 Unicode 字符,所以从解码你的字节数组开始。

use Encode qw( decode );
my $decoded_text = decode("UTF-8", $encoded_text);

只有这样你才能转义 Unicode 字符。

( my $escaped_text = $decoded_text ) =~
   s/([^\x0A\x20-\x5B\x5D-\x7E])/sprintf("\\u%04X", ord($1))/eg;

例如,

$ perl -CSDA -MEncode=decode -E'
   my $encoded_text = "\xC3\x89\x72\x69\x63\x20\xE2\x99\xA5\x20\x50\x65\x72\x6c";
   my $decoded_text = decode("UTF-8", $encoded_text);
   say $decoded_text;
   ( my $escaped_text = $decoded_text ) =~
      s/([^\x0A\x20-\x5B\x5D-\x7E])/sprintf("\\u%04X", ord($1))/eg;
   say $escaped_text;
'
Éric ♥ Perl
\u00C9ric \u2665 Perl

【讨论】:

  • 请注意,这种方法会增加歧义:超过 0xFFFF 的代码点与后跟 ASCII 数字的较短代码点无法区分(此外,它将转义 0 .. 31 范围内的大多数 ASCII 字符,包括制表符/回车符(或 MacOS 经典版上的换行符 :-) - 我会在那里使用 s/([^[:ascii:]])/.../eg)。
  • 对于 U+FFFF 上的代码点未定义该方案,我无能为力。转义控制字符是件好事。
  • 我不知道 perl 但 \uxxxx 是使用代理对为 U+FFFF 以上的代码点定义的:\uHHHH\uLLLL。例如U+20000:\ud840\udc00
  • @Esailija,你说的是 JSON。 OP 没有提到任何关于 JSON 的内容。他要求将代码点编码为\uXXXX。如果他想要 JSON,他应该使用 JSON::XS。
  • @ikegami JSON 是什么意思?我在 C#、java、javascript 和 python 2.7 中对其进行了测试。这些都支持星体平面的 \u 符号中的代理对。
猜你喜欢
  • 2011-01-12
  • 1970-01-01
  • 1970-01-01
  • 2012-12-02
  • 1970-01-01
  • 2015-09-25
  • 2017-09-05
  • 1970-01-01
相关资源
最近更新 更多