Dlaczego słowa „znaki” (w) nie pasują dokładnie pod pragmą locale?
Kiedy jause locale
, niektóre znaki z mojej lokalizacji (et_EE.UTF-8) nie są dopasowane\w
i nie widzę tam żadnego powodu.
Oprócz ASCII, estoński używa sześciu kolejnych znaków:
õäöüšž
W moim skrypcie testowym poniżej używam ich$string
z trzema dodatkowymi znakami specjalnymiðŋц
(które nie należą do alfabetu estońskiego).
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 '';
}
Próbowałem z Perlem 5.10.1 i 5.14.2 i obaj dali mi taki wynik:
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: ðŋšžõäöüц
šžŋц
õäöüšžðŋц
Czego nie oczekiwałem?
główny problem: poniżejuse locale
miałem nadzieję\w
dopasować wszystkie moje sześć znaków, ale wynikšžŋц
jest dość dziwny. Dlaczego takie mecze? Zperlrecharclass czytam:Dla punktów kodowych powyżej 255 ... w pasuje do tego, co pasuje do p {Word} w tym zakresie. ... W przypadku punktów kodowych poniżej 256 ... jeśli obowiązują reguły ustawień regionalnych ... w pasuje do rodzimego znaku podkreślenia platformy plus to, co ustawienia regionalne uznają za alfanumeryczne.
Więc,\w
pasuje tam znaki powyżej 255, ale nie pasuje do „niezależnie od ustawień regionalnych, które są alfanumeryczne”. Czemu? Ten sam czas sortowania w ustawieniach regionalnych działa dobrze (i bez ustawień regionalnych), wynikðŋšžõäöüц
jest prawidłowa kolejność, która pokazuje, że są prawidłowo reprezentowane właściwe znaki. AFAIU, sortowanie nie mogłoby działać bez ich znajomości „niezależnie od ustawień regionalnych, które są alfanumeryczne”. Lub?
setlocale
daje wynik tylko w locale-pragma. Jak mogę przetestować, które ustawienia regionalne są skuteczne dla zakresu?nie spodziewałem się, że wszystkie znaki są pisane dużymi literami w każdym przypadku testowym. AFAIUuc
ilc
powinien być zależny od ustawień regionalnych. W pierwszym przypadku myślałem, że wszystkie będą mniejsze, ale przy użyciu ustawień regionalnych czekałem, aż pierwszych sześć znaków będzie dużych liter, podczas gdy inne nie. Tylko przypadek, kiedy czekałem na wszystkie znaki, był trzeci. Widzę, że tęsknię za czymś ważnym tutaj. Ups, teraz znalazłemlc
docs: "W przeciwnym razie, jeśli WYRAŻ ma ustawioną flagę UTF-8: semantyka Unicode jest używana do zmiany wielkości liter." Flaga UTF-8 jest zawsze ustawiona na moim$string
, więc to dostało odpowiedź podczas pisania.Za pomocąlocale
do sortowania i\p{Word}
dopasowywanie jest dla mnie do przyjęcia, ale nadal używałbym kilku wskazówek: dlaczego\w
nie działa tak, jak oczekiwałem?