【发布时间】:2012-08-30 18:03:13
【问题描述】:
令我惊恐的是,我刚刚发现 chr 不适用于 Unicode,尽管它可以做一些事情。手册页几乎很清楚
返回字符集中由该 NUMBER 表示的字符。例如,chr(65)" 在 ASCII 或 Unicode 中都是“A”,而 chr(0x263a) 是 Unicode 笑脸。
确实,我可以使用打印笑脸
perl -e 'print chr(0x263a)'
但是像chr(0x00C0) 这样的东西不起作用。我看我的perl v5.10.1有点老了,但是当我在源代码中粘贴各种奇怪的字母时,一切都很好。
我尝试过use utf8 和use encoding 'utf8' 之类的有趣内容,我还没有尝试过use v5.12 和use feature 'unicode_strings' 之类的有趣内容,因为它们不适用于我的版本,我在胡闹与Encode::decode 一起发现我不需要解码,因为我没有要解码的字节数组。我阅读的文档比以往任何时候都多,发现了很多有趣的东西,但没有任何帮助。它看起来有点像Unicode Bug,但没有给出可用的解决方案。而且我不关心整个字符串的语义,我只需要一个微不足道的函数。
那么如何将一个数字转换为一个由与之对应的单个字符组成的字符串,例如real_chr(0xC0) eq 'À' 成立呢?
我得到的第一个答案解释了关于 IO 的一切,但我仍然不明白为什么
#!/usr/bin/perl -w
use strict;
use utf8;
use encoding 'utf8';
print chr(0x00C0) eq 'À' ? 'eq1' : 'ne1', " - ", chr(0x263a) eq '☺' ? 'eq1' : 'ne1', "\n";
print 'À' =~ /\w/ ? "match1" : "no_match1", " - ", chr(0x00C0) =~ /\w/ ? "match2" : "no_match2", "\n";
打印
ne1 - eq1
match1 - no_match2
表示手动输入的'À'与chr(0x00C0)不同。而且,前者是单词组成字符(正确!),而后者不是(但应该是!)。
【问题讨论】:
-
@D.Shawley:Linux 2.6.32-42-generic,x86_64 GNU/Linux,Ubuntu 10.4,所以 utf8 是原生的
-
Á 的 UTF8 八位字节序列是
C3 81C1是 ISO-8859-1 代码点。我的 Perlfu 有点弱,或者我会提出一个答案。 -
一些文档在这方面很薄弱,但是 UTF-8 实现,即使在后面的 Perl 5.10.1 中也相当强大。在你在 Perl 中使用 Unicode 之前,我建议阅读 perlunitut 和 perluniintro。在您的情况下,
chr不是问题,而是您没有为 UTF-8 编码和解码字符串。如果您要输出 UTF-8(或任何其他编码),您的字符串需要先在输出时转换为八位字节。 -
@ikegami:删除它会将输出更改为
eq1 - eq1; match1 - no_match2。所以我有两个相等的字符串,其中只有一个匹配。 -
在 Perl 5.14 之前的任何东西中对 Unicode 正则表达式的支持都被破坏了。在 Perl 5.14 中,您的第二个正则表达式在没有
use encoding和附加/u修饰符的情况下被修复。见Character set modifiers in perlre