目錄

名稱

Unicode::Collate - Unicode 校對演算法

語法

use Unicode::Collate;

#construct
$Collator = Unicode::Collate->new(%tailoring);

#sort
@sorted = $Collator->sort(@not_sorted);

#compare
$result = $Collator->cmp($a, $b); # returns 1, 0, or -1.

注意:@not_sorted$a$b 中的字串會根據 Perl 的 Unicode 支援進行詮釋。請參閱 perlunicodeperluniintroperlunitutperlunifaqutf8。否則,您可以使用 preprocess 或在之前對它們進行解碼。

說明

這個模組是 Unicode 技術標準 #10 (又稱 UTS #10) - Unicode 校對演算法 (又稱 UCA) 的實作。

建構函式和調整

new 方法會傳回一個校對器物件。如果 new() 沒有參數,校對器應該執行預設校對。

$Collator = Unicode::Collate->new(
   UCA_Version => $UCA_Version,
   alternate => $alternate, # alias for 'variable'
   backwards => $levelNumber, # or \@levelNumbers
   entry => $element,
   hangul_terminator => $term_primary_weight,
   highestFFFF => $bool,
   identical => $bool,
   ignoreName => qr/$ignoreName/,
   ignoreChar => qr/$ignoreChar/,
   ignore_level2 => $bool,
   katakana_before_hiragana => $bool,
   level => $collationLevel,
   long_contraction => $bool,
   minimalFFFE => $bool,
   normalization  => $normalization_form,
   overrideCJK => \&overrideCJK,
   overrideHangul => \&overrideHangul,
   preprocess => \&preprocess,
   rearrange => \@charList,
   rewrite => \&rewrite,
   suppress => \@charList,
   table => $filename,
   undefName => qr/$undefName/,
   undefChar => qr/$undefChar/,
   upper_before_lower => $bool,
   variable => $variable,
);
UCA_Version

如果提供了 UCA 的修訂版本 (以前稱為「追蹤版本」) 號碼,校對時會模擬該修訂版本的行為。如果省略,則會使用 UCA_Version() 的傳回值。

支援下列修訂版本。預設值為 43。

  UCA       Unicode Standard         DUCET (@version)
-------------------------------------------------------
   8              3.1                3.0.1 (3.0.1d9)
   9     3.1 with Corrigendum 3      3.1.1
  11             4.0.0
  14             4.1.0
  16             5.0.0
  18             5.1.0
  20             5.2.0
  22             6.0.0
  24             6.1.0
  26             6.2.0
  28             6.3.0
  30             7.0.0
  32             8.0.0
  34             9.0.0
  36            10.0.0
  38            11.0.0
  40            12.0.0
  41            12.1.0
  43            13.0.0

* UCA_Version 22 和 24 的 long_contraction 如下所述。

* 自 UCA_Version 22 起,非字元 (例如 U+FFFF) 不會被忽略,而且可以覆寫。

* 自 UCA_Version 22 起,超出範圍的碼點 (大於 U+10FFFF) 不會被忽略,而且可以覆寫。

* 完全可忽略的字元會被忽略,且不會中斷使用 `UCA_Version` 9 和 11 的縮寫。

* 在 `UCA_Version` 9 中,變數和某些行為後的可忽略字元處理方式已變更。

* 視為 CJK 統一表意文字的字元(例如 `overrideCJK`)取決於 `UCA_Version`。

* 許多韓文字母在 `UCA_Version` 20 中被指定,這將影響 `hangul_terminator`。

替換

-- 請參閱 UTS #10 第 8 版的 3.2.2 替換加權。

為了向後相容,`alternate`(舊名稱)可用作 `variable` 的別名。

反向

-- 請參閱 UTS #10 的 3.4 反向重音。

backwards => $levelNumber or \@levelNumbers

反向加權;例如法語中的第 2 級(附加符號順序)。如果省略(或 `$levelNumber` 為 `undef` 或 `\@levelNumbers` 為 `[]`),則在所有層級中向前。

輸入

-- 請參閱 UTS #10 的 5 調整;9.1 Allkeys 檔案格式。

如果相同的字元(或字元序列)透過 `table` 存在於校對元素表中,則對校對元素的對應會被覆寫。如果不存在,則會另外定義對應。

entry => <<'ENTRY', # for DUCET v4.0.0 (allkeys-4.0.0.txt)
0063 0068 ; [.0E6A.0020.0002.0063] # ch
0043 0068 ; [.0E6A.0020.0007.0043] # Ch
0043 0048 ; [.0E6A.0020.0008.0043] # CH
006C 006C ; [.0F4C.0020.0002.006C] # ll
004C 006C ; [.0F4C.0020.0007.004C] # Ll
004C 004C ; [.0F4C.0020.0008.004C] # LL
00F1      ; [.0F7B.0020.0002.00F1] # n-tilde
006E 0303 ; [.0F7B.0020.0002.00F1] # n-tilde
00D1      ; [.0F7B.0020.0008.00D1] # N-tilde
004E 0303 ; [.0F7B.0020.0008.00D1] # N-tilde
ENTRY

entry => <<'ENTRY', # for DUCET v4.0.0 (allkeys-4.0.0.txt)
00E6 ; [.0E33.0020.0002.00E6][.0E8B.0020.0002.00E6] # ae ligature as <a><e>
00C6 ; [.0E33.0020.0008.00C6][.0E8B.0020.0008.00C6] # AE ligature as <A><E>
ENTRY

注意:UCA 檔案格式中的碼位(在 ';' 之前)必須是 Unicode 碼位(定義為十六進位),但不是原生碼位。因此,`0063` 必須永遠表示 `U+0063`,而不是 `"\x63"` 的字元。

加權可能會因校對元素表而異。因此,請確保在 `entry` 中定義的加權與透過 `table` 載入的校對元素表中的加權一致。

在 DUCET v4.0.0 中,`C` 的主要加權為 `0E60`,`D` 的主要加權為 `0E6D`。因此,將 `CH` 的主要加權設定為 `0E6A`(作為 `0E60` 和 `0E6D` 之間的值)會使順序為 `C < CH < D`。準確來說,DUCET 已經有一些字元介於 `C` 和 `D` 之間:主要加權為 `0E64` 的小寫大寫 `C`(`U+1D04`)、主要加權為 `0E65` 的 c 鉤/C 鉤(`U+0188/U+0187`),以及主要加權為 `0E69` 的 c 卷曲(`U+0255`)。然後,`CH` 的主要加權 `0E6A` 會使 `CH` 的順序介於 c 卷曲和 `D` 之間。

hangul_terminator

-- 請參閱 UTS #10 的 7.1.4 尾隨加權。

如果給定一個真值(非零但應該是正值),它將作為終結符主要加權新增到每個標準韓文字節的結尾。終結符的次要和任何更高的加權都設定為零。如果值為假或不存在 `hangul_terminator` 鍵,則不會執行終結符加權的插入。

韓文字節的邊界是根據《Unicode 標準》和《HangulSyllableType.txt》中的連接韓文字母行為來確定的。

實作備註:(1) 對於擴充對應(Unicode 字元對應至一系列的校對元素),即使在韓文字節邊界存在,也不會在校對元素之間加入終止符。終止符的加入僅限於最後一個校對元素的下一位置。

(2) 非連接韓文字母(相容性字母、半形字母和封閉字母)不會自動終止於終止符主權重。這些字元可能需要事先在校對元素表中包含終止符。

highestFFFF

-- 參閱 2.4 調整後的非字元權重,UTS #35 (LDML) 第 5 部分:校對。

如果參數設為 true,U+FFFF 會有最高的優先權重。當布林值 $coll->ge($str, "abc")$coll->le($str, "abc\x{FFFF}") 為 true 時,預期 $str"abc" 或其他優先同等值開頭。$str 可以是 "abcd""abc012",但不能包含 U+FFFF,例如 "abc\x{FFFF}xyz"

$coll->le($str, "abc\x{FFFF}") 的運作方式幾乎與 $coll->lt($str, "abd") 相同,但後者有一個問題,就是你應該知道哪個字母在 c 的後面。對於某些語言,ch 是下一個字母,"abch" 大於 "abc\x{FFFF}",但小於 "abd"

注意:這等於 (entry => 'FFFF ; [.FFFE.0020.0005.FFFF]')。除了 U+FFFF 之外的任何其他字元都可以由 entry 調整。

identical

-- 參閱 A.3 確定性比較,UTS #10。

預設情況下,權重相等的字串應相等,即使其碼點不相等。完全可忽略的字元會被忽略。

如果參數設為 true,則會使用最終的決勝級別。如果在 level 指定的所有級別的比較後未發現權重的差異,則會執行碼點比較。對於決勝比較,排序金鑰會附加原始字串的碼點。完全可忽略的字元不會被忽略。

如果套用 preprocess 和/或 normalization,則會使用它們之後的字串碼點(預設為 NFD)。

ignoreChar
ignoreName

-- 參閱 3.6 可變權重,UTS #10。

讓表格中的項目完全可忽略;亦即,如同權重在所有層級皆為零。

透過 ignoreChar,任何與 qr/$ignoreChar/ 相符的字元將會被忽略。透過 ignoreName,任何名稱(在 table 檔案中以註解形式提供)與 qr/$ignoreName/ 相符的字元將會被忽略。

例如,當 'a' 和 'e' 可忽略時,'element' 等於 'lament'(或 'lmnt')。

ignore_level2

-- 參閱 5.1 參數調整,UTS #10。

預設情況下,區分大小寫的比較(即第 3 層級差異)不會忽略重音符號(即第 2 層級差異)。

如果將參數設為 true,即使考量大小寫,重音符號(和其他主要可忽略字元)也會被忽略。

注意:level 應為 3 或更大。

katakana_before_hiragana

-- 參閱 7.2 三級權重表格,UTS #10。

預設情況下,平假名在片假名前面。如果將參數設為 true,則會反過來。

注意:此參數天真地假設任何平假名/片假名區別都必須出現在第 3 層級,且其在第 3 層級的權重必須與 UTS #10 中 7.3.1 所述相同。如果您定義違反此需求的校對元素,此參數將無法有效運作。

level

-- 參閱 4.3 表單排序金鑰,UTS #10。

設定最大層級。任何高於指定層級的層級都會被忽略。

Level 1: alphabetic ordering
Level 2: diacritic ordering
Level 3: case ordering
Level 4: tie-breaking (e.g. in the case when variable is 'shifted')

ex.level => 2,

如果省略,最大值為第 4 層級。

注意:DUCET 在第 4 層級包含超過 0xFFFF 的權重。但此模組僅使用 0xFFFF 以內的權重。當 variable 為 'blanked' 或 'non-ignorable'(除了 'shifted' 和 'shift-trimmed')時,第 4 層級可能不可靠。

另請參閱 identical

long_contraction

-- 參閱 3.8.2 DUCET 的結構良好性、4.2 產生陣列,UTS #10。

如果將參數設為 true,對於包含三個或更多字元的縮寫(在此稱為「長縮寫」),將會處理初始子字串。例如,縮寫 ABC,其中 A 為起始字元,而 B 和 C 為非起始字元(具有非零組合字元類別的字元),即使沒有 AB 作為縮寫,也會被偵測到。

預設值:通常為 false。如果 UCA_Version 為 22 或 24,且 long_contraction 的值未在 new() 中指定,則會隱含設定為 true。這是為了通過 Unicode 6.0.0 和 6.1.0 的相符性測試。

change() 僅明確處理 long_contraction。如果 long_contraction 未在 change() 中指定,即使 UCA_Version 已變更,long_contraction 也不會變更。

限制:掃描非開頭字母是一條路(無回溯)。如果找到 AB 但未找到 ABC,則可能找不到第一個字元為 A 且第二個字元不為 B 的其他長縮寫。

(normalization => undef) 下,將略過非連續縮寫的偵測步驟。

注意:DUCET 中的下列縮寫未考慮在步驟 S2.1.1 至 S2.1.3 中,在這些步驟中它們是非連續的。

0FB2 0F71 0F80 (TIBETAN VOWEL SIGN VOCALIC RR)
0FB3 0F71 0F80 (TIBETAN VOWEL SIGN VOCALIC LL)

例如,在 NFD 中,藏文元音符號元音 RR組合式波浪符號覆蓋U+0344)為 0FB2 0344 0F71 0F80。在此情況下,偵測到 0FB2 0F80藏文元音符號元音 R),而非 0FB2 0F71 0F80。插入的 0344 使 0FB2 0F71 0F80 成為非連續,且缺少縮寫 0FB2 0F71 禁止偵測 0FB2 0F71 0F80

minimalFFFE

-- 參閱 1.1.1 U+FFFE,UTS #35 (LDML) 第 5 部分:排序。

如果將參數設為 true,U+FFFE 具有最小主要權重。"$a1\x{FFFE}$a2""$b1\x{FFFE}$b2" 之間的比較會先在第 1 層級比較 $a1$b1,然後在第 1 層級比較 $a2$b2,如下所示。

"ab\x{FFFE}a"
"Ab\x{FFFE}a"
"ab\x{FFFE}c"
"Ab\x{FFFE}c"
"ab\x{FFFE}xyz"
"abc\x{FFFE}def"
"abc\x{FFFE}xYz"
"aBc\x{FFFE}xyz"
"abcX\x{FFFE}def"
"abcx\x{FFFE}xyz"
"b\x{FFFE}aaa"
"bbb\x{FFFE}a"

注意:這等於 (entry => 'FFFE ; [.0001.0020.0005.FFFE]')U+FFFE 以外的任何其他字元都可以透過 entry 來調整。

normalization

-- 參閱 4.1 正規化,UTS #10。

如果指定,字串會在準備排序金鑰前正規化(正規化會在預處理後執行)。

Unicode::Normalize::normalize() 接受的形式名稱將套用為 $normalization_form。可接受的名稱包括 'NFD''NFC''NFKD''NFKC'。有關詳細資訊,請參閱 Unicode::Normalize::normalize()。如果省略,則使用 'NFD'

normalization 會在 preprocess(如果已定義)後執行。

此外,可以使用特殊值 undef"prenormalized",儘管它們與 Unicode::Normalize::normalize() 無關。

如果將 undef(非字串 "undef")明確傳遞為此金鑰的值,則不會執行任何正規化(如果不需要任何正規化,這可能會讓調整更容易)。在 (normalization => undef) 下,只會解析連續縮寫;例如,即使 A-ring(和 A-ring-cedilla)在 Z 之後排序,A-cedilla-ring 仍會與 A 主要相等。在這個點上,(normalization => undef, preprocess => sub { NFD(shift) }) 不等於 (normalization => 'NFD')

(normalization => "prenormalized") 的情況下,不會執行任何正規化,但會執行與組合字元的非連續縮寫。因此,(normalization => 'prenormalized', preprocess => sub { NFD(shift) }) 等於 (normalization => 'NFD')。如果來源字串經過精細的預正規化,(normalization => 'prenormalized') 可以節省正規化的時間。

除了 (normalization => undef),需要 Unicode::Normalize(另請參閱 注意事項)。

overrideCJK

-- 參閱 7.1 衍生校對元素,UTS #10。

預設情況下,中日韓統一表意文字會依照 Unicode 編碼點順序排列,但中日韓統一表意文字區塊中的文字會小於中日韓統一表意文字擴充區 A 等中的文字。

In the CJK Unified Ideographs block:
U+4E00..U+9FA5 if UCA_Version is 8, 9 or 11.
U+4E00..U+9FBB if UCA_Version is 14 or 16.
U+4E00..U+9FC3 if UCA_Version is 18.
U+4E00..U+9FCB if UCA_Version is 20 or 22.
U+4E00..U+9FCC if UCA_Version is 24 to 30.
U+4E00..U+9FD5 if UCA_Version is 32 or 34.
U+4E00..U+9FEA if UCA_Version is 36.
U+4E00..U+9FEF if UCA_Version is 38, 40 or 41.
U+4E00..U+9FFC if UCA_Version is 43.

In the CJK Unified Ideographs Extension blocks:
Ext.A (U+3400..U+4DB5)   if UCA_Version is  8 to 41.
Ext.A (U+3400..U+4DBF)   if UCA_Version is 43.
Ext.B (U+20000..U+2A6D6) if UCA_Version is  8 to 41.
Ext.B (U+20000..U+2A6DD) if UCA_Version is 43.
Ext.C (U+2A700..U+2B734) if UCA_Version is 20 or later.
Ext.D (U+2B740..U+2B81D) if UCA_Version is 22 or later.
Ext.E (U+2B820..U+2CEA1) if UCA_Version is 32 or later.
Ext.F (U+2CEB0..U+2EBE0) if UCA_Version is 36 or later.
Ext.G (U+30000..U+3134A) if UCA_Version is 43.

透過 overrideCJK,可以覆寫中日韓統一表意文字(包括擴充區)的排序。

例如:依照 JIS 編碼點順序排列中日韓統一表意文字。

overrideCJK => sub {
    my $u = shift;             # get a Unicode codepoint
    my $b = pack('n', $u);     # to UTF-16BE
    my $s = your_unicode_to_sjis_converter($b); # convert
    my $n = unpack('n', $s);   # convert sjis to short
    [ $n, 0x20, 0x2, $u ];     # return the collation element
},

傳回值可能是如上所示的第 1 到第 4 個權重的陣列參考。傳回值可能是如上所示的整數作為主要權重。如果傳回 undef,將會使用預設的衍生校對元素。

overrideCJK => sub {
    my $u = shift;             # get a Unicode codepoint
    my $b = pack('n', $u);     # to UTF-16BE
    my $s = your_unicode_to_sjis_converter($b); # convert
    my $n = unpack('n', $s);   # convert sjis to short
    return $n;                 # return the primary weight
},

傳回值可能是包含陣列參考、整數或 undef 的清單。

例如:忽略所有中日韓統一表意文字。

overrideCJK => sub {()}, # CODEREF returning empty list

 # where ->eq("Pe\x{4E00}rl", "Perl") is true
 # as U+4E00 is a CJK unified ideograph and to be ignorable.

如果傳遞假值(包括 undef),overrideCJK 沒有作用。$Collator->change(overrideCJK => 0) 會重設舊值。

但是,在 tableentry 中為中日韓統一表意文字指定權重仍然有效。如果明確傳遞 undef 作為此金鑰的值,則中日韓統一表意文字的權重會被視為未定義。但是,當 UCA_Version > 8 時,(overrideCJK => undef) 沒有特殊意義。

注意:除了這些之外,12 個中日韓相容表意文字(U+FA0EU+FA0FU+FA11U+FA13U+FA14U+FA1FU+FA21U+FA23U+FA24U+FA27U+FA28U+FA29)也會被視為中日韓統一表意文字。但是,當您使用 DUCET 時,無法透過 overrideCJK 覆寫這些文字,因為表格中包含這些文字的權重。tableentry 優先於 overrideCJK

overrideHangul

-- 參閱 7.1 衍生校對元素,UTS #10。

預設情況下,韓文字母會分解成韓語字母,即使 (normalization => undef)。但是,韓文字母的對應關係可能會被覆寫。

此參數的工作方式類似於 overrideCJK,因此請參閱該處的範例。

如果您想要覆寫韓文字母的對應關係,NFD 和 NFKD 不適用,因為 NFD 和 NFKD 會在覆寫之前分解韓文字母。FCD 可能會視情況分解韓文字母。

如果傳遞假值(但不是 undef),overrideHangul 沒有作用。$Collator->change(overrideHangul => 0) 會重設舊值。

如果明確傳遞 undef 作為此金鑰的值,韓文字母的權重會被視為未定義,而不會分解成韓語字母。但是,在 tableentry 中定義韓文字母的權重仍然有效。

overrideOut

-- 請參閱 7.1.1 處理格式錯誤的代碼單元序列,UTS #10。

Perl 似乎允許超出範圍的值(大於 0x10FFFF)。預設情況下,當 UCA_Version >= 22 時,超出範圍的值會以 U+FFFD(替換字元)替換,或當 UCA_Version <= 20 時,會被忽略。

UCA_Version >= 22 時,超出範圍的值的權重可以被覆寫。儘管 tableentry 可用於它們,但超出範圍的值太多。

overrideOut 可以演算法方式執行它。此參數的工作原理類似於 overrideCJK,因此請參閱那裡的範例。

範例:忽略所有超出範圍的值。

overrideOut => sub {()}, # CODEREF returning empty list

如果傳遞假值(包括 undef),則 overrideOut 不會產生作用。$Collator->change(overrideOut => 0) 會重設舊值。

關於 U+FFFD 的注意事項

UCA 建議出於安全原因不應忽略超出範圍的值。例如,"pe\x{110000}rl" 不應等於 "perl"。但是,U+FFFD 在 Unicode 6.0.0 至 6.2.0 的 DUCET 中錯誤地對應到一個可變整理元素,這表示當 variable 不是 Non-ignorable 時,超出範圍的值將會被忽略。

U+FFFD 的對應在 Unicode 6.3.0 中已得到修正。請參閱 http://www.unicode.org/reports/tr10/tr10-28.html#Trailing_Weights(7.1.4 尾隨權重)。這樣的修正會由此重製。

overrideOut => sub { 0xFFFD }, # CODEREF returning a very large integer

此解決方法自 Unicode 6.3.0 以來是不必要的。

preprocess

-- 請參閱 5.4 預處理,UTS #10。

如果指定,則在形成排序鍵之前,會使用代碼引用來預處理每個字串。

範例:刪除英文冠詞,例如「a」或「the」。然後,「the pen」會在「a pencil」之前。

preprocess => sub {
      my $str = shift;
      $str =~ s/\b(?:an?|the)\s+//gi;
      return $str;
   },

preprocess 會在 normalization(如果已定義)之前執行。

範例:解碼舊版編碼(例如 shift-jis)中的字串

$sjis_collator = Unicode::Collate->new(
    preprocess => \&your_shiftjis_to_unicode_decoder,
);
@result = $sjis_collator->sort(@shiftjis_strings);

注意:從代碼引用傳回的字串將根據 Perl 的 Unicode 支援進行詮釋。請參閱 perlunicodeperluniintroperlunitutperlunifaqutf8

rearrange

-- 請參閱 3.5 重新排列,UTS #10。

未以邏輯順序編碼且要重新排列的字元。如果 UCA_Version 等於或小於 11,預設為

rearrange => [ 0x0E40..0x0E44, 0x0EC0..0x0EC4 ],

如果您想禁止任何重新排列,請傳遞 undef[](對應到空清單)作為此金鑰的值。

如果 UCA_Version 等於或大於 14,預設為 [](即不重新排列)。

根據 UCA 第 9 版,此參數不應使用;但目前並未提出警告。

rewrite

如果指定,則會使用 coderef 來改寫 tableentry 中的行。coderef 會取得每一行,然後應根據 UCA 檔案格式傳回已改寫的行。如果 coderef 傳回空行,則會略過該行。

例如,將任何主要可忽略字元改寫為次要可忽略字元

rewrite => sub {
    my $line = shift;
    $line =~ s/\[\.0000\..{4}\..{4}\./[.0000.0000.0000./g;
    return $line;
},

此範例顯示改寫權重。rewrite 可影響碼點、權重和名稱。

注意table 可用來使用另一個表格檔案;準備一個已修改的表格一次會比每次讀取未修改的表格時改寫行更有效率。

suppress

-- 請參閱 3.12 特殊用途指令,UTS #35 (LDML) 第 5 部分:排序。

即使在 table 中定義了這些縮寫,但從指定字元開始的縮寫也會被抑制。

俄語和一些使用西里爾字母的語言範例

suppress => [0x0400..0x0417, 0x041A..0x0437, 0x043A..0x045F],

其中 0x0400 代表 U+0400,西里爾大寫字母 IE 帶有重音符號。

注意:透過 entry 的縮寫不會被抑制。

table

-- 請參閱 3.8 預設 Unicode 排序元素表格,UTS #10。

如果需要,您可以使用另一個排序元素表格。

表格檔案應位於 @INC 中的 Unicode/Collate 目錄中。例如,如果檔案名稱為 Foo.txt,則會在 @INC 中將表格檔案搜尋為 Unicode/Collate/Foo.txt

預設使用 allkeys.txt(作為 DUCET 的檔案名稱)。如果您要準備自己的表格檔案,則建議使用 allkeys.txt 以外的其他名稱,以避免名稱空間衝突。

注意:當使用 XSUB 時,會在建置此模組時編譯 DUCET,且可能在執行時節省時間。明確指出 (table => 'allkeys.txt'),或使用另一個表格,或使用 ignoreCharignoreNameundefCharundefNamerewrite 將會阻止此模組使用已編譯的 DUCET。

如果明確傳遞 undef 作為此金鑰的值,則不會讀取任何檔案(但您可以透過 entry 定義排序元素)。

在沒有任何表格檔案的情況下定義排序元素表格的典型方式

$onlyABC = Unicode::Collate->new(
    table => undef,
    entry => << 'ENTRIES',
0061 ; [.0101.0020.0002.0061] # LATIN SMALL LETTER A
0041 ; [.0101.0020.0008.0041] # LATIN CAPITAL LETTER A
0062 ; [.0102.0020.0002.0062] # LATIN SMALL LETTER B
0042 ; [.0102.0020.0008.0042] # LATIN CAPITAL LETTER B
0063 ; [.0103.0020.0002.0063] # LATIN SMALL LETTER C
0043 ; [.0103.0020.0008.0043] # LATIN CAPITAL LETTER C
ENTRIES
 );

如果使用 ignoreNameundefName,則應在每一行的註解中(在 # 之後)指定字元名稱。

undefChar
undefName

-- 參閱 6.3.3 減少字庫,UTS #10。

將整理元素取消定義,如同它在 table 中未指派。這會減少表格的大小。如果未指派的字元出現在要整理的字串中,排序金鑰會由其碼點作為單字元整理元素而產生,因為它大於任何其他已指派的整理元素(在未指派字元中的碼點順序中)。不過,最好忽略您不熟悉且可能永遠不會使用的字元。

透過 undefChar,任何與 qr/$undefChar/ 相符的字元都將取消定義。透過 undefName,任何名稱(在 table 檔案中以註解形式提供)與 qr/$undefName/ 相符的字元都將取消定義。

範例:超出 BMP 的字元的整理權重未儲存在物件中

undefChar => qr/[^\0-\x{fffd}]/,
upper_before_lower

-- 參閱 6.6 大小寫比較,UTS #10。

預設情況下,小寫在在於大寫之前。如果將參數設為 true,則會反轉此順序。

注意:此參數單純假設任何大小寫區分都必須發生在層級 3,且它們在層級 3 的權重必須與 UTS #10 的 7.3.1 中所述相同。如果您定義與此需求不同的整理元素,則此參數將無法有效運作。

variable

-- 參閱 3.6 可變權重,UTS #10。

此金鑰允許對表格中標有星號的變數整理元素進行變數加權(注意:許多標點符號和符號在 allkeys.txt 中都是變數)。

variable => 'blanked', 'non-ignorable', 'shifted', or 'shift-trimmed'.

這些名稱不區分大小寫。預設情況下(如果省略規格),會採用「已轉移」。

'Blanked'        Variable elements are made ignorable at levels 1 through 3;
                 considered at the 4th level.

'Non-Ignorable'  Variable elements are not reset to ignorable.

'Shifted'        Variable elements are made ignorable at levels 1 through 3
                 their level 4 weight is replaced by the old level 1 weight.
                 Level 4 weight for Non-Variable elements is 0xFFFF.

'Shift-Trimmed'  Same as 'shifted', but all FFFF's at the 4th level
                 are trimmed.

整理方法

@sorted = $Collator->sort(@not_sorted)

對字串清單進行排序。

$result = $Collator->cmp($a, $b)

傳回 1(當 $a 大於 $b)或 0(當 $a 等於 $b)或 -1(當 $a 小於 $b)。

$result = $Collator->eq($a, $b)
$result = $Collator->ne($a, $b)
$result = $Collator->lt($a, $b)
$result = $Collator->le($a, $b)
$result = $Collator->gt($a, $b)
$result = $Collator->ge($a, $b)

它們的工作方式與它們同名的運算子相同。

eq : whether $a is equal to $b.
ne : whether $a is not equal to $b.
lt : whether $a is less than $b.
le : whether $a is less than $b or equal to $b.
gt : whether $a is greater than $b.
ge : whether $a is greater than $b or equal to $b.
$sortKey = $Collator->getSortKey($string)

-- 參閱 4.3 表單排序金鑰,UTS #10。

傳回一個排序鍵。

您可以使用二進位比較來比較排序鍵,並使用 UCA 取得字串比較結果。

$Collator->getSortKey($a) cmp $Collator->getSortKey($b)

   is equivalent to

$Collator->cmp($a, $b)
$sortKeyForm = $Collator->viewSortKey($string)

將排序鍵轉換成其表示形式。如果 UCA_Version 為 8,輸出會稍微不同。

use Unicode::Collate;
my $c = Unicode::Collate->new();
print $c->viewSortKey("Perl"),"\n";

# output:
# [0B67 0A65 0B7F 0B03 | 0020 0020 0020 0020 | 0008 0002 0002 0002 | FFFF FFFF FFFF FFFF]
#  Level 1               Level 2               Level 3               Level 4

搜尋方法

matchgmatchsubstgsubst 方法分別像 m//m//gs///s///g 一樣運作,但它們不會辨識任何樣式,只會辨識文字子字串。

免責聲明:如果 $Collatorpreprocessnormalization 參數為 true,呼叫這些方法 (indexmatchgmatchsubstgsubst) 會造成錯誤,因為位置和長度可能與指定字串中的位置和長度不同。

rearrangehangul_terminator 參數會被忽略。katakana_before_hiraganaupper_before_lower 參數不會影響比對和搜尋,因為大小寫無關緊要。

$position = $Collator->index($string, $substring[, $position])
($position, $length) = $Collator->index($string, $substring[, $position])

如果 $substring$string 的一部分相符,則在標量環境中傳回相符部分第一次出現的位置;在清單環境中,傳回相符部分的位置和長度的二元清單。

如果 $substring$string 的任何部分都不相符,則在標量環境中傳回 -1,在清單環境中傳回空清單。

例如,當 $str 的內容為 "Ich muß studieren Perl." 時,您會說以下內容,其中 $sub"MüSS"

my $Collator = Unicode::Collate->new( normalization => undef, level => 1 );
                                   # (normalization => undef) is REQUIRED.
my $match;
if (my($pos,$len) = $Collator->index($str, $sub)) {
    $match = substr($str, $pos, $len);
}

並在 $match 中取得 "muß",因為 "muß" 主要等於 "MüSS"

$match_ref = $Collator->match($string, $substring)
($match) = $Collator->match($string, $substring)

如果 $substring$string 的一部分相符,在標量內容中,傳回 對應 第一個相符部分的參照(如果相符,$match_ref 永遠為 true,因為每個參照都是 true);在清單內容中,傳回相符部分的第一個出現。

如果 $substring$string 的任何部分都不相符,在標量內容中傳回 undef,在清單內容中傳回一個空清單。

例如:

    if ($match_ref = $Collator->match($str, $sub)) { # scalar context
	print "matches [$$match_ref].\n";
    } else {
	print "doesn't match.\n";
    }

     or

    if (($match) = $Collator->match($str, $sub)) { # list context
	print "matches [$match].\n";
    } else {
	print "doesn't match.\n";
    }
@match = $Collator->gmatch($string, $substring)

如果 $substring$string 的一部分相符,傳回所有相符部分(或在標量內容中傳回相符次數)。

如果 $substring$string 的任何部分都不相符,傳回一個空清單。

$count = $Collator->subst($string, $substring, $replacement)

如果 $substring$string 的一部分相符,相符部分的第一個出現會被 $replacement 取代($string 會被修改),並傳回 $count(永遠等於 1)。

$replacement 可以是一個 CODEREF,將相符部分作為引數,並傳回一個字串來取代相符部分(有點類似於 s/(..)/$coderef->($1)/e)。

$count = $Collator->gsubst($string, $substring, $replacement)

如果 $substring$string 的一部分相符,相符部分的所有出現會被 $replacement 取代($string 會被修改),並傳回 $count

$replacement 可以是一個 CODEREF,將相符部分作為引數,並傳回一個字串來取代相符部分(有點類似於 s/(..)/$coderef->($1)/eg)。

例如:

my $Collator = Unicode::Collate->new( normalization => undef, level => 1 );
                                   # (normalization => undef) is REQUIRED.
my $str = "Camel donkey zebra came\x{301}l CAMEL horse cam\0e\0l...";
$Collator->gsubst($str, "camel", sub { "<b>$_[0]</b>" });

# now $str is "<b>Camel</b> donkey zebra <b>came\x{301}l</b> <b>CAMEL</b> horse <b>cam\0e\0l</b>...";
# i.e., all the camels are made bold-faced.

 Examples: levels and ignore_level2 - what does camel match?
---------------------------------------------------------------------------
 level  ignore_level2  |  camel  Camel  came\x{301}l  c-a-m-e-l  cam\0e\0l
-----------------------|---------------------------------------------------
   1        false      |   yes    yes      yes          yes        yes
   2        false      |   yes    yes      no           yes        yes
   3        false      |   yes    no       no           yes        yes
   4        false      |   yes    no       no           no         yes
-----------------------|---------------------------------------------------
   1        true       |   yes    yes      yes          yes        yes
   2        true       |   yes    yes      yes          yes        yes
   3        true       |   yes    no       yes          yes        yes
   4        true       |   yes    no       yes          no         yes
---------------------------------------------------------------------------
 note: if variable => non-ignorable, camel doesn't match c-a-m-e-l
       at any level.

其他方法

%old_tailoring = $Collator->change(%new_tailoring)
$modified_collator = $Collator->change(%new_tailoring)

變更指定鍵的值,並傳回已變更的部分。

$Collator = Unicode::Collate->new(level => 4);

$Collator->eq("perl", "PERL"); # false

%old = $Collator->change(level => 2); # returns (level => 4).

$Collator->eq("perl", "PERL"); # true

$Collator->change(%old); # returns (level => 2).

$Collator->eq("perl", "PERL"); # false

並非所有 (key,value) 都可以變更。請參閱 @Unicode::Collate::ChangeOK@Unicode::Collate::ChangeNG

在純量環境中,傳回修改後的排序器(但它不是原始排序器的複製)。

$Collator->change(level => 2)->eq("perl", "PERL"); # true

$Collator->eq("perl", "PERL"); # true; now max level is 2nd.

$Collator->change(level => 4)->eq("perl", "PERL"); # false
$version = $Collator->version()

傳回排序器物件所使用的 table 檔案所根據的 Unicode 標準版本號碼(字串)。如果表格不包含版本列(以 @version 開頭),則傳回 "unknown"

UCA_Version()

傳回此模組查閱的 UTS #10 校訂版本號碼,應與納入的 DUCET 相符。

Base_Unicode_Version()

傳回此模組查閱的 UTS #10 版本號碼,應與納入的 DUCET 相符。

EXPORT

不會匯出任何方法。

INSTALL

雖然此模組可以在沒有任何 table 檔案的情況下使用,但為了輕鬆使用此模組,建議在 UCA 格式中安裝一個表格檔案,方法是將其複製到目錄 <a place in @INC>/Unicode/Collate 下。

最優先選擇的是「預設 Unicode 排序元素表格」(又稱 DUCET),可從 Unicode 聯盟網站取得

http://www.unicode.org/Public/UCA/

http://www.unicode.org/Public/UCA/latest/allkeys.txt
(latest version)

如果未安裝 DUCET,建議手動將檔案從 http://www.unicode.org/Public/UCA/latest/allkeys.txt 複製到 <a place in @INC>/Unicode/Collate/allkeys.txt。

CAVEATS

正規化

使用 normalization 參數需要 Unicode::Normalize 模組(請參閱 Unicode::Normalize)。

如果您不需要它(例如,當您不需要處理任何組合字元時),請明確指定 (normalization => undef)

-- 請參閱 UTS #10 的 6.5 避免正規化。

相符性測試

UCA 的相符性測試可在 http://www.unicode.org/Public/UCA/ 取得。

對於 CollationTest_SHIFTED.txt,應使用透過 Unicode::Collate->new( ) 建立的排序器;對於 CollationTest_NON_IGNORABLE.txt,應使用透過 Unicode::Collate->new(variable => "non-ignorable", level => 3) 建立的排序器。

如果 UCA_Version 是 26 或更新版本,則優先使用 identical 層級;應使用 Unicode::Collate->new(identical => 1)Unicode::Collate->new(identical => 1, variable => "non-ignorable", level => 3)

需要 Unicode::Normalize 才能嘗試一致性測試。

EBCDIC 支援為實驗性質。

作者、著作權和授權

perl 的 Unicode::Collate 模組是由 SADAHIRO Tomoyuki, <SADAHIRO@cpan.org> 編寫的。此模組的著作權為 SADAHIRO Tomoyuki, 2001-2021。日本。保留所有權利。

此模組為免費軟體;您可以在與 Perl 相同的條款下重新散布或修改它。

Unicode/Collate/allkeys.txt 檔案從 http://www.unicode.org/Public/UCA/13.0.0/allkeys.txt 原文複製。對於此檔案,著作權 (c) 2020 Unicode, Inc.;根據 http://www.unicode.org/terms_of_use.html 中的使用條款散布。

另請參閱

Unicode 校對演算法 - UTS #10

http://www.unicode.org/reports/tr10/

預設 Unicode 校對元素表 (DUCET)

http://www.unicode.org/Public/UCA/latest/allkeys.txt

UCA 的一致性測試

http://www.unicode.org/Public/UCA/latest/CollationTest.html

http://www.unicode.org/Public/UCA/latest/CollationTest.zip

韓文字節類型

http://www.unicode.org/Public/UNIDATA/HangulSyllableType.txt

Unicode 正規化表單 - UAX #15

http://www.unicode.org/reports/tr15/

Unicode 地區資料標記語言 (LDML) - UTS #35

http://www.unicode.org/reports/tr35/