如何将两个代码点转换为一个?如果这是处理组合图形素的默认方法,那么如何避免呢?
> my $a = "a" ~ 0x304.chr
ā
> $a.codes
1
> $a.ords
(257)UPD:在读取文档时,我看到所有输入都已经规范化了:
Perl6默认情况下对所有输入和输出应用规范化,但存储为UTF8-C8的文件名除外。
那么,是否有一种避免规范化的方法,即获取输入并在不改变编码的情况下处理它?
发布于 2017-10-19 21:45:38
根据Unicode报告(请参阅这里),有些字符有多种表示方式。根据该报告:
某些人物被称为单身汉。在正常化之后,它们永远不会留在文本中。例子包括angstrom和ohm符号,它们分别映射到它们的普通字母对应的带环和omega。 ..。 许多字符被称为规范组合,或预先组合的字符。在D形式中,它们被分解;在C形式中,它们通常是预先组合的。
在您提供的示例中,$a包含可以用两种方式表示的字符串。首先,它对应于U+0101 (拉丁文小写字母A与马克龙),这是一个Unicode码点。第二,它可以表示为两个代码点,它们组合成一个等价字符(U+0061拉丁文小写字母A,U+0304组合马克龙)。
这两种表示是NFC和NFD的基础。这些被称为规范化形式,因为它们允许使用可用的最简洁或最解构的表示形式定期表示字符。有些组合字符可能在Unicode表中有两个条目(例如Ohm和Big ),但是规范化的表单只能映射到一个条目。
NFD将所有字符分解成用于生成这些字符的所有代码点的列表,确保不使用预先组合的字符。
Perl6自动使用NFC表示,但是您可以通过在Str上使用NFD转换方法获得NFD (或D集成)版本。
my $a = "a" ~ 0x304.chr;
say $a.codes; # OUTPUT: 1
# This is because the concatenation
# is using NFC by default.
say $a.ords; # OUTPUT: (257)
say $a.NFD.codes; # OUTPUT: 2
say $a.NFD.list; # OUTPUT: (97 772)NFC和NFD都很有用,但目的不同。据我所知,无法避免输入的规范化,但可以使用NFC和NFD转换方法将输入转换为所需的表示。
https://stackoverflow.com/questions/46837841
复制相似问题