Perl6 可以不区分大小写地 cmp 两个字符串吗?
Can Perl6 cmp two strings case insensitively?
我正在进行排序,希望将 alpha 值的 cmp 控制为不区分大小写(即 https://perl6.org/archive/rfc/143.html)。
可能有一些 :i 副词吗?
Perl 6 目前没有这个选项,但它是一种非常多变的语言,所以让我们添加它。
由于现有的 proto
不允许命名值,我们必须添加一个新的,或者写一个 only
子。
(也就是说,除了可选的 only
之外,您可以只使用下面的 multi
。)
这只适用于词法,所以如果你写这篇文章,你可能想根据你正在做的事情将 proto
/only
子标记为可导出。
proto sub infix:<leg> ( \a, \b, *% ){*}
multi sub infix:<leg> ( \a, \b, :ignore-case(:$i) ){
$i
?? &CORE::infix:<leg>( fc(a) , fc(b) )
!! &CORE::infix:<leg>( a , b )
}
say 'a' leg 'A'; # More
say 'a' leg 'A' :i; # Same
say 'a' leg 'A' :!i; # More
say 'a' leg 'A' :ignore-case; # Same
请注意 :$i
是 :i( $i )
的缩写,因此两个命名参数可以写为:
:ignore-case( :i( $i ) )
我还使用了 fc()
的子形式而不是 .fc
的方法形式,因为它允许使用字符串的本机形式而不会导致自动装箱。
In order to do case-insensitive comparison, you can use .fc
(fold-case). The problem is that people tend to use .lc
or .uc
, and it
does seem to work within the ASCII range, but fails on other
characters. This is not just a Perl 6 trap, the same applies to other
languages.
例如:
say ‘groß’.fc eq ‘GROSS’.fc; # ← RIGHT; True
如果您正在使用正则表达式,则无需使用 .fc
,您可以使用 :i
(:ignorecase
) 副词代替。
您可以通过代码块进行排序。如果块的元数为一,则在进行比较时它对两个元素都起作用。这是一个示例,显示了上一个答案中的 'fc'。
> my @a = <alpha BETA gamma DELTA>;
[alpha BETA gamma DELTA]
> @a.sort
(BETA DELTA alpha gamma)
> @a.sort(*.fc)
(alpha BETA DELTA gamma)
如果您想要 "dictionary" 排序顺序,@timotimo 在他们建议 collate
和 coll
进行排序时走在正确的轨道上。
对列表中的任何内容使用 collate()
对其进行排序。如果您需要自定义排序,请使用 coll
作为中缀运算符。
$ perl6
To exit tyype 'exit' or '^D'
> <a Zp zo zz ab 9 09 91 90>.collate();
(09 9 90 91 a ab zo Zp zz)
> <a Zp zo zz ab 9 09 91 90>.sort: * coll *;
(09 9 90 91 a ab zo Zp zz)
我正在进行排序,希望将 alpha 值的 cmp 控制为不区分大小写(即 https://perl6.org/archive/rfc/143.html)。
可能有一些 :i 副词吗?
Perl 6 目前没有这个选项,但它是一种非常多变的语言,所以让我们添加它。
由于现有的 proto
不允许命名值,我们必须添加一个新的,或者写一个 only
子。
(也就是说,除了可选的 only
之外,您可以只使用下面的 multi
。)
这只适用于词法,所以如果你写这篇文章,你可能想根据你正在做的事情将 proto
/only
子标记为可导出。
proto sub infix:<leg> ( \a, \b, *% ){*}
multi sub infix:<leg> ( \a, \b, :ignore-case(:$i) ){
$i
?? &CORE::infix:<leg>( fc(a) , fc(b) )
!! &CORE::infix:<leg>( a , b )
}
say 'a' leg 'A'; # More
say 'a' leg 'A' :i; # Same
say 'a' leg 'A' :!i; # More
say 'a' leg 'A' :ignore-case; # Same
请注意 :$i
是 :i( $i )
的缩写,因此两个命名参数可以写为:
:ignore-case( :i( $i ) )
我还使用了 fc()
的子形式而不是 .fc
的方法形式,因为它允许使用字符串的本机形式而不会导致自动装箱。
In order to do case-insensitive comparison, you can use
.fc
(fold-case). The problem is that people tend to use.lc
or.uc
, and it does seem to work within the ASCII range, but fails on other characters. This is not just a Perl 6 trap, the same applies to other languages.
例如:
say ‘groß’.fc eq ‘GROSS’.fc; # ← RIGHT; True
如果您正在使用正则表达式,则无需使用 .fc
,您可以使用 :i
(:ignorecase
) 副词代替。
您可以通过代码块进行排序。如果块的元数为一,则在进行比较时它对两个元素都起作用。这是一个示例,显示了上一个答案中的 'fc'。
> my @a = <alpha BETA gamma DELTA>;
[alpha BETA gamma DELTA]
> @a.sort
(BETA DELTA alpha gamma)
> @a.sort(*.fc)
(alpha BETA DELTA gamma)
如果您想要 "dictionary" 排序顺序,@timotimo 在他们建议 collate
和 coll
进行排序时走在正确的轨道上。
对列表中的任何内容使用 collate()
对其进行排序。如果您需要自定义排序,请使用 coll
作为中缀运算符。
$ perl6
To exit tyype 'exit' or '^D'
> <a Zp zo zz ab 9 09 91 90>.collate();
(09 9 90 91 a ab zo Zp zz)
> <a Zp zo zz ab 9 09 91 90>.sort: * coll *;
(09 9 90 91 a ab zo Zp zz)