在 unix 命令行上在 Unicode 规范化形式之间进行转换

在 unix 命令行上在 Unicode 规范化形式之间进行转换

在 Unicode 中,某些字符组合具有不止一种表示形式。

例如,字符A可以表示为

  • “ä”,即代码点 U+00E4(c3 a4UTF-8 编码中的两个字节),或作为
  • “ä”,即两个代码点 U+0061 U+0308(61 cc 88UTF-8 中的三个字节)。

根据 Unicode 标准,这两种表示形式是等效的,但“规范化形式”不同,请参阅UAX #15:Unicode 规范化形式

unix工具箱有各种文本转换工具,sed,t,图标,我想到了Perl。如何在命令行上快速轻松地进行 NF 转换?

答案1

您可以使用uconv效用来自重症监护室正常化是通过音译实现的(-x)。

$ uconv -x any-nfd <<<ä | hd
00000000  61 cc 88 0a                                       |a...|
00000004
$ uconv -x any-nfc <<<ä | hd
00000000  c3 a4 0a                                          |...|
00000003

在 Debian、Ubuntu 和其他衍生品上,uconv是在libicu-dev软件包中。在 Fedora、Red Hat 和其他衍生版本以及 BSD 移植中,它位于icu软件包中。

答案2

Pythonunicodedata在其标准库中有模块,允许通过函数翻译 Unicode 表示unicodedata.normalize()形式:

import unicodedata
 
s1 = 'Spicy Jalape\u00f1o'
s2 = 'Spicy Jalapen\u0303o'

t1 = unicodedata.normalize('NFC', s1)
t2 = unicodedata.normalize('NFC', s2)
print(t1 == t2) 
print(ascii(t1)) 
 
t3 = unicodedata.normalize('NFD', s1)
t4 = unicodedata.normalize('NFD', s2)
print(t3 == t4)
print(ascii(t3))

使用 Python 3.x 运行:

$ python3 test.py
True
'Spicy Jalape\xf1o'
True
'Spicy Jalapen\u0303o'

Python 不太适合 shell 语句,但如果您不想创建外部脚本,也可以这样做:

$ python3 -c $'import unicodedata\nprint(unicodedata.normalize("NFC", "ääääää"))'
ääääää

对于 Python 2.x,您必须添加编码行 ( # -*- coding: utf-8 -*-) 并使用 u 字符将字符串标记为 Unicode:

$ python -c $'# -*- coding: utf-8 -*-\nimport unicodedata\nprint(unicodedata.normalize("NFC", u"ääääää"))'
ääääää

答案3

使用hexdump工具查看:

echo  -e "ä\c" |hexdump -C 

00000000  61 cc 88                                          |a..|
00000003  

使用 iconv 进行转换并使用 hexdump 再次检查:

echo -e "ä\c" | iconv -f UTF-8-MAC -t UTF-8 |hexdump -C

00000000  c3 a4                                             |..|
00000002

printf '\xc3\xa4'
ä

答案4

coreutils 有一个补丁来获得正确的unorm.我在 4 字节 wchar 上工作得很好。跟随http://crashcourse.housegordon.org/coreutils-multibyte-support.html#unorm 剩下的问题是 2 字节 wchar 系统(cygwin、windows 以及 32 位上的 aix 和Solaris),它们需要将上层平面的代码点转换为代理对,反之亦然,而底层的 libunistring/gnulib 还无法处理这个问题。

我确实将这些补丁维护在https://github.com/rurban/coreutils/tree/multibyte

Perl 有unichars工具,它还在命令行上执行各种规范化形式。http://search.cpan.org/dist/Unicode-Tussle/script/unichars

相关内容