在 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 フ | hex0000 83 74
与 $ LANG=de_AT.UTF-8 bash$ echo -n フ | uniquote -b\xE3\x83\x95$ echo -n フ | hex0000 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 的单行代码的主要内容,如果未能解决你的问题,请参考以下文章