如何用代码点而不是字形替换Perl 6中的字符串?

问题描述 投票:8回答:2

我需要使用Perl 6从字符串中删除变音符号。我尝试这样做:

my $hum = 'חוּם';
$ahm.subst(/<-[\c[HEBREW LETTER ALEF] .. \c[HEBREW LETTER TAV]]>/, '', :g);

我想删除所有不在HEBREW LETTER ALEF(א)和HEBREW LETTER TAV(ת)之间的字符。我希望以下代码返回“חום”,但它会返回“חם”。

我想会发生的事情是,默认情况下Perl 6的工作原理是字形,认为它是一个字形,并删除了所有字母。通过字形工作通常是明智的,但在我的情况下,我需要通过代码点来工作。

我试图找到一个能让它通过codepoint工作但却找不到它的副词。也许在Perl 6中还有一种方法可以使用Unicode属性来排除变音符号,或仅包含字母,但我也找不到。

谢谢!

regex unicode perl6
2个回答
9
投票

我的正则表达式很弱,所以我会选择一个不那么神奇的解决方案。

首先,您可以通过samemark删除所有标记:

'חוּם'.samemark('a')

其次,您可以通过.NFD分解字形并对单个代码点进行操作 - 例如,仅使用属性Grapheme_Base保存值 - 然后重新构造字符串:

Uni.new('חוּם'.NFD.grep(*.uniprop('Grapheme_Base'))).Str

如果是混合字符串,希伯来字符的剥离标记可能如下所示:

$str.subst(:g, /<:Script<Hebrew>>+/, *.Str.samemark('a'));

3
投票

这是一个简单的方法:

my $hum = 'חוּם';
my $min = "\c[HEBREW LETTER ALEF]".ord;
my $max = "\c[HEBREW LETTER TAV]".ord;
my @ords;
for $hum.ords {
    @ords.push($_) if $min ≤ $_ ≤ $max; 
}
say join('', @ords.map: { .chr });

输出:

חום
© www.soinside.com 2019 - 2024. All rights reserved.