Perl 为什么不’;t字字符(\w)是否在use locale pragma下匹配?
当我Perl 为什么不’;t字字符(\w)是否在use locale pragma下匹配?,perl,sorting,unicode,utf-8,locale,Perl,Sorting,Unicode,Utf 8,Locale,当我使用locale时,我的locale(et_EE.UTF-8)中的一些字符与\w不匹配,我看不出任何原因 除ASCII外,爱沙尼亚语还使用了六个字符: õäöšž 在下面的测试脚本中,我在$string中使用了它们,并添加了三个特殊字符ð331;ц(不属于爱沙尼亚字母表) 我尝试使用Perl 5.10.1和5.14.2,两者都提供了这样的输出: nothing LOCALE: et_EE.UTF-8 et_EE.UTF-8 UC: ÕÄÖÜŠŽ ÐŊЦ SORT: äðõöüŋšžц õä
使用locale
时,我的locale(et_EE.UTF-8)中的一些字符与\w
不匹配,我看不出任何原因
除ASCII外,爱沙尼亚语还使用了六个字符:
õäöšž
在下面的测试脚本中,我在$string
中使用了它们,并添加了三个特殊字符ð331;ц
(不属于爱沙尼亚字母表)
我尝试使用Perl 5.10.1和5.14.2,两者都提供了这样的输出:
nothing
LOCALE: et_EE.UTF-8 et_EE.UTF-8
UC: ÕÄÖÜŠŽ ÐŊЦ
SORT: äðõöüŋšžц
õäöüšžðŋц
õäöüšžðŋц
locale
LOCALE: et_EE.UTF-8 et_EE.UTF-8
UC: ÕÄÖÜŠŽ ÐŊЦ
SORT: ðŋšžõäöüц
šžŋц
õäöüšžðŋц
utf8::all
LOCALE: et_EE.UTF-8 et_EE.UTF-8
UC: ÕÄÖÜŠŽ ÐŊЦ
SORT: äðõöüŋšžц
õäöüšžðŋц
õäöüšžðŋц
utf8::all + locale
LOCALE: et_EE.UTF-8 et_EE.UTF-8
UC: ÕÄÖÜŠŽ ÐŊЦ
SORT: ðŋšžõäöüц
šžŋц
õäöüšžðŋц
有什么不符合我的期望
- 主要问题:在
我希望下使用locale
匹配我所有的六个字符,但结果是\w
非常奇怪。为什么会有这样的比赛?我读到:ŠŠŠŠ
\w
匹配255以上的字符,但不匹配“语言环境认为是字母数字的任何内容”。为什么?同时,locale下的排序工作正常(而没有locale则不行),结果的顺序正确,这表明正确表示了正确的字符。此外,如果不知道sort的“语言环境认为是字母数字”的话,sort就无法正常工作。还是
- 我认为
setlocale
只在locale pragma下给出结果。我如何测试,哪种语言环境对范围有效李>
- 我没想到每个测试用例中的所有字符都是大写的。AFAIU
uc
和lc
应取决于区域设置。在第一种情况下,我认为它们都是小写的,但使用locale,我等待前六个字符是大写的,而其他字符不是。唯一一个我等了很久的案例是第三个。我看我错过了一些重要的事情。哎呀,现在我在lc
文档中发现:“否则,如果EXPR设置了UTF-8标志:将Unicode语义用于大小写更改。”UTF-8标志始终设置在我的$string
上,因此在编写过程中得到了答案
使用locale
进行排序和\p{Word}
进行匹配对我来说是可以接受的,但我仍然会使用一些提示:为什么\w
不能像我预期的那样工作 请不要使用断开的使用locale
pragma
请,请,请使用Unicode::Collate::Locale
进行区域设置排序。它使用CLDR规则,并且是完全可移植的,并且不依赖于不可靠的POSIX语言环境,而这些语言环境根本不能很好地工作
如果按代码点排序,则会得到无意义的结果,但如果使用由爱沙尼亚语言环境构造的Unicode::Collate::Locale
对象进行排序,
你得到了一些合理的东西:
Codepoint排序:äðõöüŋšŠ
爱沙尼亚类:ðŋšõääî
此外,当您进行这种原始代码点排序时,您会受到规范化问题的严重影响。考虑:
NFC/NFD按码点排序不同
NFC码点排序:äðõöüŋšž
NFD码点排序:ãõšûž240; 331;
爱沙尼亚语中的NFC/NFD排序相同
NFC爱沙尼亚分类:ðŋšõäää
NFD爱沙尼亚分类:ðŋšžõâôû
这是制作这一切的演示程序
#!/usr/bin/env perl
#
# et-demo - show how to handle Estonian collation correctly
#
# Tom Christinansen <tchrist@perl.com>
# Fri Feb 22 19:27:51 MST 2013
use v5.14;
use utf8;
use strict;
use warnings;
use warnings FATAL => "utf8";
use open qw(:std :utf8);
use Unicode::Normalize;
use Unicode::Collate::Locale;
main();
exit();
sub graphemes(_) {
my($str) = @_;
my @graphs = $str =~ /\X/g;
return @graphs;
}
sub same_diff($$) {
my($s1, $s2) = @_;
no locale;
if (NFC($s1) eq NFC($s2)) {
return "SAME";
} else {
return "DIFFERENT";
}
}
sub stringy {
return join("" => @_);
}
sub cp_sort {
no locale;
return sort @_;
}
sub et_sort {
state $collator = # we want Estonian here:
Unicode::Collate::Locale->new(locale => "et");
return $collator->sort(@_);
}
sub main {
my $orig = "õäöüšž ðŋц";
say " Codepoint sort: ", cp_sort(graphemes($orig));
say " Estonian sort: ", et_sort(graphemes($orig));
my $nfc = NFC($orig);
my $nfc_cp_sort = stringy cp_sort(graphemes($nfc));
my $nfc_et_sort = stringy et_sort(graphemes($nfc));
my $nfd = NFD($orig);
my $nfd_cp_sort = stringy cp_sort(graphemes($nfd));
my $nfd_et_sort = stringy et_sort(graphemes($nfd));
say "NFC/NFD sort by codepoint is ",
same_diff($nfc_cp_sort, $nfd_cp_sort);
say "NFC Codepoint sort: ", $nfc_cp_sort;
say "NFD Codepoint sort: ", $nfd_cp_sort;
say "NFC/NFD sort in estonian is ",
same_diff($nfc_et_sort, $nfd_et_sort);
say "NFC Estonian sort: ", $nfc_et_sort;
say "NFD Estonian sort: ", $nfd_et_sort;
}
#/usr/bin/env perl
#
#et演示-演示如何正确处理爱沙尼亚排序规则
#
#汤姆·克里斯蒂南森
#2013年2月22日星期五19:27:51 MST
使用v5.14;
使用utf8;
严格使用;
使用警告;
使用致命警告=>“utf8”;
使用开放式qw(:标准:utf8);
使用Unicode::规范化;
使用Unicode::Collate::Locale;
main();
退出();
子图形{
我的($str)=@;
my@graphs=$str=~/\X/g;
返回@图;
}
子相同_差异($$){
我的($s1,$s2)=@;
没有地点;
if(NFC($s1)均衡NFC($s2)){
返回“相同”;
}否则{
返回“不同”;
}
}
次弦{
返回联接(“=>@”;
}
子cp_排序{
没有地点;
返回排序@;
}
子类{
state$collator=#我们想要爱沙尼亚语:
Unicode::Collate::Locale->new(Locale=>“et”);
返回$collator->sort(@);
}
副总管{
我的$orig=“õäèðŋè”;
说“码点排序:”,cp_排序(graphemes($orig));
说“爱沙尼亚排序:”,等排序(graphemes($orig));
my$nfc=nfc($orig);
my$nfc_cp_sort=stringy cp_sort(graphemes($nfc));
my$nfc_et_sort=stringy et_sort(graphemes($nfc));
my$nfd=nfd($orig);
my$nfd_cp_sort=stringy cp_sort(graphemes($nfd));
my$nfd_et_sort=stringy et_sort(graphemes($nfd));
说“NFC/NFD按码点排序是”,
相同差异($nfc\U cp\U排序,$nfd\U cp\U排序);
说“NFC码点排序:”,$NFC\U cp\U排序;
说“NFD码点排序:”,$NFD\U cp\U排序;
说“爱沙尼亚语中的NFC/NFD排序为”,
相同差异($nfc排序,$nfd排序);
说“NFC爱沙尼亚排序:”,$NFC_et_排序;
说“NFD爱沙尼亚排序:”,$NFD_et_排序;
}
这就是您应该如何处理区域设置排序规则。另请参见大量示例。请不要使用断开的使用locale
pragma
请,请,请使用Unicode::Collate::Locale
进行区域设置排序。它使用CLDR规则,并且是完全可移植的,并且不依赖于不可靠的POSIX语言环境,而这些语言环境根本不能很好地工作
如果按代码点排序,则会得到无意义的结果,但如果使用由爱沙尼亚语言环境构造的Unicode::Collate::Locale
对象进行排序,
你得到了一些合理的东西:
Codepoint排序:äðõöüŋšŠ
爱沙尼亚类:ðŋšõääî
此外,当您进行这种原始代码点排序时,您会受到规范化问题的严重影响。考虑:
NFC/NFD按码点排序不同
NFC码点排序:äðõöüŋšž
NFD码点排序:ãõšu
#!/usr/bin/env perl
#
# et-demo - show how to handle Estonian collation correctly
#
# Tom Christinansen <tchrist@perl.com>
# Fri Feb 22 19:27:51 MST 2013
use v5.14;
use utf8;
use strict;
use warnings;
use warnings FATAL => "utf8";
use open qw(:std :utf8);
use Unicode::Normalize;
use Unicode::Collate::Locale;
main();
exit();
sub graphemes(_) {
my($str) = @_;
my @graphs = $str =~ /\X/g;
return @graphs;
}
sub same_diff($$) {
my($s1, $s2) = @_;
no locale;
if (NFC($s1) eq NFC($s2)) {
return "SAME";
} else {
return "DIFFERENT";
}
}
sub stringy {
return join("" => @_);
}
sub cp_sort {
no locale;
return sort @_;
}
sub et_sort {
state $collator = # we want Estonian here:
Unicode::Collate::Locale->new(locale => "et");
return $collator->sort(@_);
}
sub main {
my $orig = "õäöüšž ðŋц";
say " Codepoint sort: ", cp_sort(graphemes($orig));
say " Estonian sort: ", et_sort(graphemes($orig));
my $nfc = NFC($orig);
my $nfc_cp_sort = stringy cp_sort(graphemes($nfc));
my $nfc_et_sort = stringy et_sort(graphemes($nfc));
my $nfd = NFD($orig);
my $nfd_cp_sort = stringy cp_sort(graphemes($nfd));
my $nfd_et_sort = stringy et_sort(graphemes($nfd));
say "NFC/NFD sort by codepoint is ",
same_diff($nfc_cp_sort, $nfd_cp_sort);
say "NFC Codepoint sort: ", $nfc_cp_sort;
say "NFD Codepoint sort: ", $nfd_cp_sort;
say "NFC/NFD sort in estonian is ",
same_diff($nfc_et_sort, $nfd_et_sort);
say "NFC Estonian sort: ", $nfc_et_sort;
say "NFD Estonian sort: ", $nfd_et_sort;
}