如何在命令行上处理utf8(使用Perl或Python)?

Fra*_*ank 15 python perl utf-8

如何在命令行上使用Perl(或Python)处理utf8?

例如,我试图将每个单词中的字符分开.对于非utf8文本,这非常容易,例如:

$ echo "abc def" | perl -ne 'my @letters = m/(.)/g; print "@letters\n"' | less
a b c   d e f
Run Code Online (Sandbox Code Playgroud)

但是使用utf8它当然不起作用:

$ echo "????????? ??" | perl -ne 'my @letters = m/(.)/g; print "@letters\n"' | less
<D0> <BE> <D0> <B4> <D0> <BE> <D0> <B1> <D1> <80> <D0> <B5> <D0> <BD> <D0> <B8> <D0> <B5>   <D0> <B7> <D0> <B0>
Run Code Online (Sandbox Code Playgroud)

因为它不知道2字节字符.

知道如何在Python中完成这个(即utf8的命令行处理)也是一件好事.

jfs*_*jfs 26

"-C"标志控制一些Perl Unicode功能(请参阅参考资料perldoc perlrun):

$ echo "????????? ??" | perl -C -pe 's/.\K/ /g'
? ? ? ? ? ? ? ? ?   ? ? 
Run Code Online (Sandbox Code Playgroud)

要指定用于stdin/stdout的编码,可以使用PYTHONIOENCODING环境变量:

$ echo "????????? ??" | PYTHONIOENCODING=utf-8 python -c'import sys
for line in sys.stdin:
    print " ".join(line.decode(sys.stdin.encoding)),
'
? ? ? ? ? ? ? ? ?   ? ? 
Run Code Online (Sandbox Code Playgroud)

如果您想在字符(字形)边界上分割文本(不在代码点上作为上面的代码),那么您可以使用/\X/正则表达式:

$ echo "????????? ??" | perl -C -pe 's/\X\K/ /g'
? ? ? ? ? ? ? ? ?   ? ? 
Run Code Online (Sandbox Code Playgroud)

请参阅Grapheme Cluster Boundaries

模块中\X支持Python .regex


Dav*_* W. 6

"嘿",我想,"这在Perl中有多难?"

事实证明这很容易.不幸的是,找出我的时间比我想象的要长.

快速浏览使用utf8告诉我,现在已经过时了.Perl的binmode看起来很有希望,但并不完全.

发现有一个Perluniintro引导我到Perlunicode说我应该看看Perlrun.然后,我发现了我在找什么.

Perl有一个命令行开关-C,可以将Perl切换为Unicode.但是,-C命令行开关还需要一些选项.您需要指定unicode中的内容.有一个方便的图表,显示各种选项.似乎perl -C本身就没问题.这结合了各种选项,相当于-CSDL-C255.但是,这意味着如果您的LOCALE未设置为unicode,则Perl将无法在Unicode中运行.

相反,你应该使用perl -CSD-perl -C63.

$ echo "????????? ??" | perl -CSD -ne 'my @letters = m/(.)/g; print "@letters\n"'
? ? ? ? ? ? ? ? ?   ? ?
Run Code Online (Sandbox Code Playgroud)

是的,有效.

您只需回答一个问题就可以学到很多东西.

  • 嗯,utf8 pragma开始时比它最终更加雄心勃勃.它被认为是更像utf8 :: all的东西. (3认同)
  • 使用utf8并不是完全过时的,只是它只有有限的目的告诉perl您的源代码是在utf8中.你需要做其他事情来摄取和弹出utf8中的数据. (2认同)