在 Perl 中编写可识别 Unicode 的单行代码

Posted

技术标签:

【中文标题】在 Perl 中编写可识别 Unicode 的单行代码【英文标题】:writing Unicode-aware one-liners in Perl 【发布时间】:2012-03-18 20:19:09 【问题描述】:

在 Perl 中编写支持 Unicode 的单行代码的正确方法是什么?显而易见的方式:

$ echo 'フーバー' | perl  -lne 'print if /フ/'  
フーバー

...乍一看似乎可以工作,但这只是一个意外:Unicode 被解释为字节,如下一个示例所示:

$ echo 'フーバー != フウバー' | perl  -mString::Diff=diff -lne 'print join(" ", diff($1, $2)) if /(.*)!=(.*)/'                                                                                 => 29
フ?[??]バー[ ]  フ???バー

仅使用-C 标志将STDIN/STDOUT 设置为UTF-8 本身是不够的:

$ echo 'フーバー' | perl -C -lne 'print if /フ/' 
[no output]

...因为现在-e 中的文本不会被解释为 Unicode。

这就是要走的路(假设一个理智的 LOCALE - 即"*.UTF‑8" 形式的一个),如下所示:

$ perl -C -Mutf8 [...]

【问题讨论】:

【参考方案1】:

是的,需要加载 utf8 pragma 才能将源代码中的“”UTF-8 序列解释为字符而不是单独的字节。

Perl 的-C 命令行开关和utf8 杂注与语言环境无关,但shell 的echo 命令不是。

【讨论】:

echo 命令不独立于语言环境是什么意思? $ LANG=ja_JP.sjis bash␤$ echo -n フ | uniquote -b␤¥x83t␤$ echo -n フ | hex␤0000 83 74$ LANG=de_AT.UTF-8 bash␤$ echo -n フ | uniquote -b␤\xE3\x83\x95␤$ echo -n フ | hex␤0000 e3 83 95【参考方案2】:

如果我需要处理 unicode,我喜欢使用 utf8::all

echo 'フーバー' | perl -Mutf8::all -lne 'print if /フ/'

PS。使用-C,您还需要提供特定的标志,AFAIK

【讨论】:

-C on its own (not followed by any number or option list) (…) has the same effect as -CSDL. 投反对票的原因是? (@daxim:感谢您清除此问题) 谢谢——那个模块看起来很有用;可惜没有类似的简单明了的内置方法来获得相同的效果。 @as.我真的很想念它有一段时间了,所以这个模块是我的救星 @as.请注意,我不是反对者。但是,我建议使用核心设施而不是utf8::all。说‑Mutf8 ‑CSAD 并不太粗略,而且您准确地知道您得到了什么。 -Mwarnings=FATAL,all 控制存在一些问题,因为 utf8::all 模块假装尝试强制执行字符串 UTF-8,但实际上向您隐藏了内置 :utf8 会及时报告为以这种方式使用的异常的错误。请参阅the recipes in the Perl Unicode Cookbook,了解仅使用核心设施的更简短示例。【参考方案3】:

在 Windows 7 中:

chcp 65001 
perl -M"charnames':full'" -E "say qqI \NHEAVY BLACK HEART PSGI."

【讨论】:

以上是关于在 Perl 中编写可识别 Unicode 的单行代码的主要内容,如果未能解决你的问题,请参考以下文章

将两个 if 语句合并为一个的 Perl 单行器

在 vim 编辑中使用 perl 单行命令

为啥我的 Perl 程序使用 Tie::File 和 Unicode/UTF-8 编码失败?

指定要处理的文件到 Perl 单行

Perl单行(Perl One-Liners)命令

如何在 Perl 中枚举所有 Unicode 规范等效序列?