当 I 时use locale
,我的语言环境(et_EE.UTF-8)中的某些字符不匹配,\w
我看不到任何原因。
除了 ASCII,爱沙尼亚语还使用了六个字符:
õäöüšž
在下面的测试脚本中,我将它们$string
与三个额外的特殊字符ðŋц
(不属于爱沙尼亚字母)一起使用。
use feature 'say';
use POSIX qw( locale_h );
{
use utf8;
my $string = "õäöüšž ðŋц";
binmode STDOUT, ":encoding(UTF-8)";
say "nothing";
say 'LOCALE: ', setlocale(LC_CTYPE), ' ', setlocale(LC_COLLATE);
say 'UC: ', uc( $string );
say 'SORT: ', sort( split(//, $string) );
say $string =~ m/\w/g;
say $string =~ m/\p{Word}/g;
say '';
}
{
use utf8;
use locale;
binmode STDOUT, ":encoding(UTF-8)";
my $string = "õäöüšž ðŋц";
say "locale";
say 'LOCALE: ', setlocale(LC_CTYPE), ' ', setlocale(LC_COLLATE);
say 'UC: ', uc( $string );
say 'SORT: ', sort( split(//, $string) );
say $string =~ m/\w/g;
say $string =~ m/\p{Word}/g;
say '';
}
{
use utf8::all;
my $string = "õäöüšž ðŋц";
say "utf8::all";
say 'LOCALE: ', setlocale(LC_CTYPE), ' ', setlocale(LC_COLLATE);
say 'UC: ', uc( $string );
say 'SORT: ', sort( split(//, $string) );
say $string =~ m/\w/g;
say $string =~ m/\p{Word}/g;
say '';
}
{
use utf8::all;
use locale;
my $string = "õäöüšž ðŋц";
say "utf8::all + locale";
say 'LOCALE: ', setlocale(LC_CTYPE), ' ', setlocale(LC_COLLATE);
say 'UC: ', uc( $string );
say 'SORT: ', sort( split(//, $string) );
say $string =~ m/\w/g;
say $string =~ m/\p{Word}/g;
say '';
}
我尝试使用 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: ðŋšžõäöüц
šžŋц
õäöüšžðŋц
什么不符合我的预期?
- 主要问题:
use locale
我希望\w
匹配我所有的六个字符,但结果šžŋц
很奇怪。为什么会有这样的比赛?从perlrecharclass我读到:
对于高于 255 的代码点 ... \w 匹配与 \p{Word} 在此范围内匹配。...对于低于 256 的代码点 ...如果区域设置规则生效 ... \w 匹配平台的本机下划线字符加上任何区域设置认为是字母数字的字符。
因此,\w
匹配 255 以上的字符,但不匹配“任何语言环境认为是字母数字的”。为什么?同时在语言环境下排序工作正常(没有语言环境不能),结果ðŋšžõäöüц
是正确的顺序,这表明有正确的字符表示。AFAIU,如果不知道“无论语言环境认为是字母数字的什么”,排序就无法正常工作。或者?
- 我认为这
setlocale
仅在 locale-pragma 下给出结果。我如何测试,哪个语言环境对范围有效? - 我没想到每个测试用例中的所有字符都是大写的。AFAIU
uc
并且lc
应该依赖于语言环境。在第一种情况下,我认为它们都会小写,但是使用语言环境我等待前六个字符大写,而其他字符则不是。唯一的情况是我等待所有字符大写,是第三个。我看到我在这里错过了一些重要的事情。糟糕,现在我从lc
文档中找到:“否则,如果 EXPR 设置了 UTF-8 标志:Unicode 语义用于大小写更改。” UTF-8 标志始终设置在 my 上$string
,因此在编写过程中得到了答案。
locale
用于排序和\p{Word}
匹配对我来说是可以接受的,但我仍然会使用一些提示:为什么不能\w
按我的预期工作?