两个相关问题。
Perl 6非常聪明,它将字形理解为一个字符,无论是一个Unicode符号(如ä
,U+00E4
)还是两个或多个组合符号(如p̄
和{{ 1}})。这个小代码
ḏ̣
给出以下输出:
my @symb;
@symb.push("ä");
@symb.push("p" ~ 0x304.chr); # "p̄"
@symb.push("ḏ" ~ 0x323.chr); # "ḏ̣"
say "$_ has {$_.chars} character" for @symb;
但有时我希望能够做到以下几点。
1)从ä has 1 character
p̄ has 1 character
ḏ̣ has 1 character
中删除变音符号。所以我需要一些像
ä
2)拆分"合并"符号分成部分,即将"ä".mymethod → "a"
分成p̄
和p
。例如。类似Combining Macron U+0304
中的以下内容:
bash
答案 0 :(得分:4)
这是我能从文档中得到的最好的 - 可能有一种更简单的方法,但我不确定。
my $in = "Él está un pingüino";
my $stripped = Uni.new($in.NFD.grep: { !uniprop($_, 'Grapheme_Extend') }).Str;
say $stripped; # El esta un pinguino
.NFD
方法将字符串转换为规范化形式D(已分解),它将字形分隔为基本代码点,并尽可能组合代码点。然后grep返回仅包含那些没有“Grapheme_Extend”属性的代码点的列表,即它删除组合代码点。然后Uni.new(...).Str
将这些代码点组装回一个字符串。
您也可以将这些部分放在一起以回答您的第二个问题; e.g:
$in.NFD.map: { Uni.new($_).Str }
将返回1个字符的字符串列表,每个字符串都有一个分解的代码点,或
$in.NFD.map(&uniname).join("\n")
将成为一个不错的小型unicode调试器。
答案 1 :(得分:4)
Perl 6在Str
类中具有出色的Unicode处理支持。要在(1)中执行您所要求的操作,您可以使用samemark
方法/例程。
根据文件:
multi sub samemark(Str:D $string, Str:D $pattern --> Str:D) method samemark(Str:D: Str:D $pattern --> Str:D)
返回
$string
的副本,其中每个字符的标记/重音信息已更改,以便与$pattern
中相应字符的标记/重音相匹配。如果$string
超过$pattern
,则$string
中的其余字符会获得与$pattern
中的最后一个字符相同的标记/重音。如果$pattern
为空,则不会进行任何更改。示例:
say 'åäö'.samemark('aäo'); # OUTPUT: «aäo» say 'åäö'.samemark('a'); # OUTPUT: «aao» say samemark('Pêrl', 'a'); # OUTPUT: «Perl» say samemark('aöä', ''); # OUTPUT: «aöä»
这既可用于从字母中删除标记/变音符号,也可用于添加它们。
对于(2),有几种方法可以做到这一点(TIMTOWTDI)。如果需要字符串中所有代码点的列表,可以使用ords
方法获取字符串中所有代码点的List
(技术上为Positional
)。
say "p̄".ords; # OUTPUT: «(112 772)»
您可以使用uniname
方法/例程来获取代码点的Unicode名称:
.uniname.say for "p̄".ords; # OUTPUT: «LATIN SMALL LETTER PCOMBINING MACRON»
或只使用uninames
方法/例程:
.say for "p̄".uninames; # OUTPUT: «LATIN SMALL LETTER PCOMBINING MACRON»
如果您只想要字符串中的代码点数,可以使用codes
:
say "p̄".codes; # OUTPUT: «2»
这与chars
不同,https://docs.microsoft.com/en-us/azure/analysis-services/analysis-services-connect只计算字符串中的字符数:
say "p̄".chars; # OUTPUT: «1»
另见@ hobbs'使用NFD
回答。
答案 2 :(得分:2)
我不能说这更好或更快,但我以这种方式剥夺了变音符号:
my $s = "åäö";
say $s.comb.map({.NFD[0].chr}).join; # output: "aao"