在Perl 6中使用修饰符符号创建字符类

Eug*_*sky 7 perl6 raku

我想创建一个用户定义的"元音"字符类,它将匹配任何文字英语元音字母(a,e,i,o,u)以及任何这些字母与任何可能的变音符号:ắắ úåų̄ẹ等

这是我试过的,但它不起作用:

> my $vowel = / <[aeiou]> <:Sk>* /
/ <[aeiou]> <:Sk>* /
> "áei" ~~ m:g/ <$vowel> /
(?e? ?i?)
Run Code Online (Sandbox Code Playgroud)

Håk*_*and 10

您可以尝试使用ignoremark:

:ignoremark或:m副词指示正则表达式引擎仅比较基本字符,并忽略其他标记,例如组合重音符号.

对于你的例子:

my $vowel = /:m<[aeiou]>/;
.say for "áeikj" ~~ m:g/ <$vowel> /;
Run Code Online (Sandbox Code Playgroud)

输出:

?á?
?e?
?i?
Run Code Online (Sandbox Code Playgroud)

  • @EugeneBarsky Iirc一个字符类表达式在[NFA](https://en.wikipedia.org/wiki/Nondeterministic_finite_automaton)上有效运行,并且许多正则表达式构造混乱了所以当前(可能是永远的)一般的正则表达式构造是不允许的字符类表达式.所以我认为你展示的"之前"的东西是要走的路.我不确定这是否得到官方支持,但在目前的Rakudo中你可以写`<!$ vowel>`而不是`<!before <$ vowel >>`并得到相同的结果. (2认同)

tim*_*imo 10

您无法将元音与组合字符匹配的原因/ <[aeiou]> <:Sk>* /是Perl 6中的字符串在字形级别上运行.在该级别,??已经只是一个字符,并且<[aeiou]>作为一个字符类已经匹配一个整个字符.

正如Håkon在另一个答案中指出的那样,正确的解决方案是使用ignoremark副词.你可以把它像正则表达式之前rx:m/ <[aeiou]> /或在其内部,甚至在不同的点上,并关闭它:m:!m.