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 支持进行解释。参见 perlunicode、perluniintro、perlunitut、perlunifaq、utf8。否则,您可以使用 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 的修订版(以前称为“跟踪版本”)号,则在排序时会模拟该修订版的行为。如果省略,则使用 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
* 请参见下方 long_contraction
在 UCA_Version
22 和 24 中的示例。
* 非字符(例如 U+FFFF)不会被忽略,并且可以从 UCA_Version
22 开始被覆盖。
* 超出范围的代码点(大于 U+10FFFF)不会被忽略,并且可以从 UCA_Version
22 开始被覆盖。
* 完全可忽略字符会被忽略,并且在 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
之间包含了一些字符:小写大写字母 C
(U+1D04
),主权重为 0E64
;c-hook/C-hook
(U+0188/U+0187
),主权重为 0E65
;c-curl
(U+0255
),主权重为 0E69
。然后,CH
的主权重 0E6A
使 CH
排列在 c-curl
和 D
之间。
-- 请参见 UTS #10 第 7.1.4 节“尾随权重”。
如果给定一个真值(非零但应为正数),它将作为终止符主权重添加到每个标准韩文字节的末尾。终止符的次要权重和任何更高权重都设置为零。如果该值为假或hangul_terminator
键不存在,则不会执行终止符权重的插入。
韩文字节的边界根据Unicode 标准和HangulSyllableType.txt中连字 Jamo 的行为确定。
实现说明:(1)对于扩展映射(Unicode 字符映射到一系列排序元素),即使存在韩文字节边界,也不会在排序元素之间添加终止符。添加终止符仅限于最后一个排序元素的下一个位置。
(2)非连字韩文字符(兼容 Jamo、半角 Jamo 和封闭字符)不会自动以终止符主权重结束。这些字符可能需要事先在排序元素表中包含终止符。
-- 请参阅 2.4 定制非字符权重,UTS #35 (LDML) 第 5 部分:排序。
如果参数设置为真,则U+FFFF
具有最高主权重。当$coll->ge($str, "abc")
和$coll->le($str, "abc\x{FFFF}")
的布尔值为真时,预期$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
进行定制。
-- 请参阅 A.3 确定性比较,UTS #10。
默认情况下,权重相等的字符串应该相等,即使它们的代码点不相等。完全可忽略字符将被忽略。
如果参数设置为真,则将使用最终的决胜局级别。如果在通过level
指定的级别进行比较后,没有发现权重的差异,则将执行代码点的比较。对于决胜局比较,排序键将附加原始字符串的代码点。完全可忽略字符不会被忽略。
如果应用了preprocess
和/或normalization
,则使用它们之后(默认情况下为 NFD)的字符串的代码点。
-- 请参阅 3.6 变量权重,UTS #10。
使表格中的条目完全不可见;即,如同所有级别的权重都为零。
通过 ignoreChar
,任何与 qr/$ignoreChar/
匹配的字符将被忽略。通过 ignoreName
,任何其名称(在 table
文件中作为注释给出)与 qr/$ignoreName/
匹配的字符将被忽略。
例如,当 'a' 和 'e' 可忽略时,'element' 等于 'lament'(或 'lmnt')。
-- 请参阅 5.1 参数化定制,UTS #10。
默认情况下,区分大小写的比较(即 3 级差异)不会忽略重音符号(即 2 级差异)。
如果参数设置为 true,则即使考虑到大小写,也会忽略重音符号(和其他主要可忽略字符)。
注意:level
应为 3 或更大。
-- 请参阅 7.2 三级权重表,UTS #10。
默认情况下,平假名在片假名前。如果参数设置为 true,则顺序反转。
注意:此参数简单地假设任何平假名/片假名区分必须发生在 3 级,并且它们在 3 级的权重必须与 UTS #10 中 7.3.1 中提到的权重相同。如果您定义了违反此要求的排序元素,则此参数将无法正常工作。
-- 请参阅 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
。
-- 请参阅 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
。如果在 change()
中未指定 long_contraction
,即使 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)
例如,TIBETAN VOWEL SIGN VOCALIC RR
与 COMBINING TILDE OVERLAY
(U+0344
) 在 NFD 中为 0FB2 0344 0F71 0F80
。在这种情况下,检测到 0FB2 0F80
(TIBETAN VOWEL SIGN VOCALIC R
),而不是 0FB2 0F71 0F80
。插入的 0344
使 0FB2 0F71 0F80
不连续,并且缺少缩写 0FB2 0F71
禁止检测 0FB2 0F71 0F80
。
-- 请参阅 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
进行定制。
-- 请参阅 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是必需的(另见CAVEAT)。
--参见7.1派生排序元素,UTS #10。
默认情况下,CJK统一表意文字按Unicode码点顺序排序,但CJK统一表意文字块中的那些小于CJK统一表意文字扩展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
,可以覆盖CJK统一表意文字(包括扩展)的排序。
例如,CJK统一表意文字按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
的列表。
例如,忽略所有CJK统一表意文字。
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)
重置旧的。
但table
或entry
中对CJK统一表意文字的权重赋值仍然有效。如果显式地将undef
作为此键的值传递,则CJK统一表意文字的权重将被视为未定义。但是,当UCA_Version
> 8时,(overrideCJK => undef)
没有特殊含义。
注意:除了它们之外,12个CJK兼容表意文字(U+FA0E
、U+FA0F
、U+FA11
、U+FA13
、U+FA14
、U+FA1F
、U+FA21
、U+FA23
、U+FA24
、U+FA27
、U+FA28
、U+FA29
)也被视为CJK统一表意文字。但是,当您使用DUCET时,它们不能通过overrideCJK
覆盖,因为表中包含它们的权重。table
或entry
优先于overrideCJK
。
--参见7.1派生排序元素,UTS #10。
默认情况下,即使 (normalization => undef)
,韩语音节也会被分解成韩语字母,但韩语音节的映射可以被覆盖。
此参数的工作原理类似于 overrideCJK
,因此请参阅该参数的示例。
如果您想覆盖韩语音节的映射,NFD 和 NFKD 不适合,因为 NFD 和 NFKD 会在覆盖之前分解韩语音节。FCD 可能根据情况分解韩语音节。
如果传递一个假值(但不是 undef
),overrideHangul
不会生效。$Collator->change(overrideHangul => 0)
会重置旧值。
如果显式地将 undef
作为此键的值传递,则韩语音节的权重将被视为未定义,不会分解成韩语字母。但 table
或 entry
中对韩语音节的权重定义仍然有效。
-- 请参阅 7.1.1 处理格式错误的代码单元序列,UTS #10。
Perl 似乎允许超出范围的值(大于 0x10FFFF)。默认情况下,当 UCA_Version
>= 22 时,超出范围的值将被替换为 U+FFFD
(替换字符),或者当 UCA_Version
<= 20 时被忽略。
当 UCA_Version
>= 22 时,可以覆盖超出范围的值的权重。虽然 table
或 entry
可用于它们,但超出范围的值太多。
overrideOut
可以通过算法执行此操作。此参数的工作原理类似于 overrideCJK
,因此请参阅该参数的示例。
例如,忽略所有超出范围的值。
overrideOut => sub {()}, # CODEREF returning empty list
如果传递一个假值(包括 undef
),overrideOut
不会生效。$Collator->change(overrideOut => 0)
会重置旧值。
关于 U+FFFD 的说明
UCA 建议出于安全原因,不应忽略超出范围的值。例如,"pe\x{110000}rl"
不应该等于 "perl"
。但是,在 Unicode 6.0.0 到 6.2.0 的 DUCET 中,U+FFFD
被错误地映射到一个可变排序元素,这意味着当 variable
不是 Non-ignorable
时,超出范围的值将被忽略。
在 Unicode 6.3.0 中,U+FFFD
的映射已得到修正。请参阅 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 以来,此解决方法不再需要。
-- 请参阅 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
(如果定义)之前执行。
例如,解码使用 legacy 编码(如 shift-jis)的字符串
$sjis_collator = Unicode::Collate->new(
preprocess => \&your_shiftjis_to_unicode_decoder,
);
@result = $sjis_collator->sort(@shiftjis_strings);
注意:从代码引用返回的字符串将根据 Perl 的 Unicode 支持进行解释。参见 perlunicode、perluniintro、perlunitut、perlunifaq、utf8。
-- 参见 3.5 重排,UTS #10。
未按逻辑顺序编码且需要重新排列的字符。如果 UCA_Version
等于或小于 11,则默认值为
rearrange => [ 0x0E40..0x0E44, 0x0EC0..0x0EC4 ],
如果要禁止任何重新排列,请将 undef
或 []
(对空列表的引用)作为此键的值传递。
如果 UCA_Version
等于或大于 14,则默认值为 []
(即不进行重新排列)。
根据 UCA 第 9 版,此参数不应使用;但目前没有发出警告。
如果指定,则代码引用用于重写 table
或 entry
中的行。代码引用将获取每一行,然后应根据 UCA 文件格式返回重写后的行。如果代码引用返回空行,则该行将被跳过。
例如,将所有主要忽略字符重写为三级忽略字符
rewrite => sub {
my $line = shift;
$line =~ s/\[\.0000\..{4}\..{4}\./[.0000.0000.0000./g;
return $line;
},
此示例显示了重写权重。rewrite
允许影响代码点、权重和名称。
注意:table
可用于使用另一个表格文件;准备一个修改后的表格一次性完成,比每次读取未修改的表格时重写行效率更高。
-- 参见 3.12 特殊用途命令,UTS #35 (LDML) 第 5 部分:排序。
以指定字符开头的缩写将被抑制,即使这些缩写是在 table
中定义的。
俄罗斯语和一些使用西里尔字母的语言的示例
suppress => [0x0400..0x0417, 0x041A..0x0437, 0x043A..0x045F],
其中 0x0400 代表 U+0400
,西里尔字母大写 IE 带重音。
注意:通过 entry
的缩写不会被抑制。
-- 参见 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')
,或使用其他表格,或使用 ignoreChar
、ignoreName
、undefChar
、undefName
或 rewrite
将阻止此模块使用编译后的 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
);
如果使用 ignoreName
或 undefName
,则字符名称应在每行上作为注释(在 #
后面)指定。
-- 请参阅 6.3.3 减少字符集,UTS #10。
将排序元素定义为未分配在 table
中。这会减小表格的大小。如果未分配的字符出现在要排序的字符串中,则排序键将由其代码点作为单个字符排序元素组成,因为它大于任何其他已分配的排序元素(在未分配字符的代码点顺序中)。但是,最好忽略您不熟悉且可能从未使用过的字符。
通过 undefChar
,任何与 qr/$undefChar/
匹配的字符都将被定义为未定义。通过 undefName
,任何其名称(在 table
文件中作为注释给出)与 qr/$undefName/
匹配的字符都将被定义为未定义。
例如,超出 BMP 字符的排序权重未存储在对象中
undefChar => qr/[^\0-\x{fffd}]/,
-- 请参阅 6.6 大小写比较,UTS #10。
默认情况下,小写字母在字母顺序上排在大写字母之前。如果参数设置为 true,则顺序将反转。
注意:此参数简单地假设任何大小写区分必须发生在级别 3,并且它们在级别 3 的权重必须与 UTS #10 中的 7.3.1 中提到的权重相同。如果您定义的排序元素与此要求不同,则此参数将无法正常工作。
-- 请参阅 3.6 变量权重,UTS #10。
此键允许对可变排序元素进行可变加权,这些元素在表格中用星号标记(注意:在 allkeys.txt 中,许多标点符号和符号是可变的)。
variable => 'blanked', 'non-ignorable', 'shifted', or 'shift-trimmed'.
这些名称不区分大小写。默认情况下(如果省略规范),将采用“shifted”。
'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
match
、gmatch
、subst
、gsubst
方法分别类似于 m//
、m//g
、s///
、s///g
,但它们不识别任何模式,只识别字面子字符串。
免责声明:如果 $Collator
的 preprocess
或 normalization
参数为真,则调用这些方法(index
、match
、gmatch
、subst
、gsubst
)会抛出异常,因为位置和长度可能与指定字符串上的位置和长度不同。
rearrange
和 hangul_terminator
参数被忽略。katakana_before_hiragana
和 upper_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
始终为真,因为每个引用都是 **真**);在列表上下文中,返回匹配部分的首次出现。
如果 $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 相对应。
不会导出任何方法。
虽然此模块可以在没有任何table
文件的情况下使用,但为了方便使用此模块,建议在 UCA 格式下安装一个table
文件,将其复制到<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
。
使用 normalization
参数需要 Unicode::Normalize 模块(参见 Unicode::Normalize)。
如果您不需要它(例如,在您不需要处理任何组合字符的情况下),请显式地分配 (normalization => undef)
。
-- 参见 6.5 避免规范化,UTS #10。
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 编写,<[email protected]>。此模块版权所有 (C) 2001-2021,SADAHIRO Tomoyuki。日本。保留所有权利。
此模块是自由软件;您可以在与 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 中的使用条款分发
http://www.unicode.org/Public/UNIDATA/HangulSyllableType.txt