Unicode::UCD - Unicode 字元資料庫
use Unicode::UCD 'charinfo';
my $charinfo = charinfo($codepoint);
use Unicode::UCD 'charprop';
my $value = charprop($codepoint, $property);
use Unicode::UCD 'charprops_all';
my $all_values_hash_ref = charprops_all($codepoint);
use Unicode::UCD 'casefold';
my $casefold = casefold($codepoint);
use Unicode::UCD 'all_casefolds';
my $all_casefolds_ref = all_casefolds();
use Unicode::UCD 'casespec';
my $casespec = casespec($codepoint);
use Unicode::UCD 'charblock';
my $charblock = charblock($codepoint);
use Unicode::UCD 'charscript';
my $charscript = charscript($codepoint);
use Unicode::UCD 'charblocks';
my $charblocks = charblocks();
use Unicode::UCD 'charscripts';
my $charscripts = charscripts();
use Unicode::UCD qw(charscript charinrange);
my $range = charscript($script);
print "looks like $script\n" if charinrange($range, $codepoint);
use Unicode::UCD qw(general_categories bidi_types);
my $categories = general_categories();
my $types = bidi_types();
use Unicode::UCD 'prop_aliases';
my @space_names = prop_aliases("space");
use Unicode::UCD 'prop_value_aliases';
my @gc_punct_names = prop_value_aliases("Gc", "Punct");
use Unicode::UCD 'prop_values';
my @all_EA_short_names = prop_values("East_Asian_Width");
use Unicode::UCD 'prop_invlist';
my @puncts = prop_invlist("gc=punctuation");
use Unicode::UCD 'prop_invmap';
my ($list_ref, $map_ref, $format, $missing)
= prop_invmap("General Category");
use Unicode::UCD 'search_invlist';
my $index = search_invlist(\@invlist, $code_point);
# The following function should be used only internally in
# implementations of the Unicode Normalization Algorithm, and there
# are better choices than it.
use Unicode::UCD 'compexcl';
my $compexcl = compexcl($codepoint);
use Unicode::UCD 'namedseq';
my $namedseq = namedseq($named_sequence_name);
my $unicode_version = Unicode::UCD::UnicodeVersion();
my $convert_to_numeric =
Unicode::UCD::num("\N{RUMI DIGIT ONE}\N{RUMI DIGIT TWO}");
Unicode::UCD 模組提供一系列函式,提供一個簡單的介面來存取 Unicode 字元資料庫。
有些函式會呼叫一個碼位引數,它可以是十進位或十六進位純量,表示平台原生字元集中的碼位(延伸至 Unicode),或是一個包含 U+
後接十六進位數字的字串,表示一個 Unicode 碼位。開頭的 0 會強制十六進位詮釋,十六進位數字(不是十進位數字)也會強制十六進位詮釋。
範例
223 # Decimal 223 in native character set
0223 # Hexadecimal 223, native (= 547 decimal)
0xDF # Hexadecimal DF, native (= 223 decimal)
'0xDF' # String form of hexadecimal (= 223 decimal)
'U+DF' # Hexadecimal DF, in Unicode's character set
(= LATIN SMALL LETTER SHARP S)
請注意 Unicode 中最大的碼位是 U+10FFFF。
use Unicode::UCD 'charinfo';
my $charinfo = charinfo(0x41);
這會傳回輸入 "代碼點引數" 的資訊,作為 Unicode 標準定義的欄位雜湊的參考。如果 "代碼點引數" 未在標準中指派(即,一般類別為 Cn
,表示「未指派」)或是非字元(表示保證永遠不會在標準中指派),則會傳回 undef
。
不適用於特定代碼點引數的欄位存在於傳回的雜湊中,且為空。
對於比此函式傳回的結果「更原始」的結果,或取得任何屬性的值(不只此函式涵蓋的少數屬性),請使用 "charprop()" 函式。
雜湊中的金鑰及其值的意義為
輸入原生 "代碼點引數" 以十六進位表示,如有需要,會在前面加上前導零,使其至少包含四個十六進位數字
代碼 的名稱,全部以大寫字母表示。有些控制類型代碼點沒有名稱。此欄位對於 代理
和 私人使用
代碼點將為空,對於其他沒有名稱的代碼點,將包含以尖括號括起來的說明,例如 <控制>
。
代碼 的一般類別的簡稱。這會符合 "general_categories()" 傳回的雜湊中的金鑰之一。
可以使用 "prop_value_aliases()" 函式取得類別名稱的所有同義詞。
代碼 在正規排序演算法中使用的組合類別編號。對於 Unicode 5.1,這在第 3.11 節 正規排序行為
中說明,可在 http://www.unicode.org/versions/Unicode5.1.0/ 取得
可以使用 "prop_value_aliases()" 函式取得組合類別編號的所有同義詞。
代碼 的雙向類型。這會符合 "bidi_types()" 傳回的雜湊中的金鑰之一。
可以使用 "prop_value_aliases()" 函式取得雙向類型名稱的所有同義詞。
如果 code 沒有分解,則為空;或是一個或多個代碼(以空格分隔),按順序表示 code 的分解。每個代碼至少有四個十六進制數字。代碼前面可以加上一個用尖括號括起來的字詞,然後是一個空格,例如 <compat>
,表示分解的類型
此分解可能是中間分解,其組成部分也可以分解。使用 Unicode::Normalize 一次取得最終分解。
如果 code 表示十進制數字,則這是其整數數值
如果 code 表示其他類數字,則這是其整數數值
如果 code 表示整數或有理數,則這是其數值。有理數表示為類似 1/4
的字串。
Y
或 N
,表示 code 在雙向文字中是否鏡像
如果 Unicode 1.0 標準中存在此碼點的名稱,且與目前名稱不同,則為 code 的名稱
從 Unicode 6.0 開始,此欄位永遠為空。
如果非空,則為 code 的大寫對應,表示為至少四個十六進制數字。這表示完整的大寫對應為單一字元,且與簡單(僅單一字元)對應相同。當此欄位為空時,表示簡單大寫對應為 code 本身;您需要其他方法(例如 "charprop()" 或 "casespec()")才能取得完整對應。
如果非空,則為 code 的小寫對應,表示為至少四個十六進位數字。這表示完整的變為對應為單一字元,且與簡單(僅單一字元)對應相同。當此欄位為空時,表示簡單的小寫對應為 code 本身;您需要其他方法(例如 "charprop()" 或 "casespec()")才能取得完整的對應。
如果非空,則為 code 的標題對應,表示為至少四個十六進位數字。這表示完整的標題對應為單一字元,且與簡單(僅單一字元)對應相同。當此欄位為空時,表示簡單的標題對應為 code 本身;您需要其他方法(例如 "charprop()" 或 "casespec()")才能取得完整的對應。
code 所屬的區塊(用於 \p{Blk=...}
)。"prop_value_aliases()" 函數可用於取得區塊名稱的所有同義詞。
請參閱 "區塊與腳本"。
code 所屬的腳本。"prop_value_aliases()" 函數可用於取得腳本名稱的所有同義詞。請注意,這是較舊的「腳本」屬性值,而非改良的「腳本擴充」值。
請參閱 "區塊與腳本"。
請注意,您無法僅根據 分解、組合、小寫、大寫 和 標題 欄位進行(解)組成和大小寫轉換;您還需要 "casespec()" 函數和 Composition_Exclusion
屬性。(或者您只需使用 lc()、uc() 和 ucfirst() 函數,以及 Unicode::Normalize 模組。)
use Unicode::UCD 'charprop';
print charprop(0x41, "Gc"), "\n";
print charprop(0x61, "General_Category"), "\n";
prints
Lu
Ll
這會傳回 "代碼點引數" 給定的第一個參數,由第二個參數給定的 Unicode 屬性的值。
傳入的屬性可以指定為 "prop_aliases()" 傳回的任何同義詞。
傳回值總是為純量,可能是字串或數字。對於具有值同義詞的屬性,此函式傳回的同義詞為最長、最具描述性的形式,也就是在純量內容中呼叫 "prop_value_aliases()" 時傳回的形式。當然,您可以在結果上呼叫 "prop_value_aliases()" 以取得其他同義詞。
傳回值比 "charinfo()" 更「成熟」。例如,"uc"
屬性值為包含輸入碼點完整大寫對應的實際字串。當完整對應與簡單對應不同時,您必須使用 charinfo
額外處理才能從其 upper
hash 元素取得此值。
應特別注意下列幾個屬性的傳回值
傳回的值為新樣式(請參閱 "舊樣式與新樣式區塊名稱")。
與 "charinfo()" 相同,結果可能是其組成部分也具有可分解性的中間分解。使用 Unicode::Normalize 在一個步驟中取得最終分解。
與 "charinfo()" 不同,此處不包含分解類型。請使用 Decomposition_Type
屬性取得分解類型。
如果輸入碼點的名稱有多個同義詞,則會將這些同義詞合併成一個以逗號分隔的字串傳回。
如果結果為分數,則會將其轉換為平台精確度的浮點數。
如果結果為多個腳本名稱,則會將這些名稱合併成一個以逗號分隔的字串傳回。
當呼叫 Perl 延伸元件的屬性,且無法以複合形式表達時,此函數目前會傳回 undef
,因為僅有的兩個可能值為 true 或 false(我想是 1 或 0)。此行為未來可能會變更,因此請勿撰寫依賴此行為的程式碼。Present_In
是 Perl 延伸元件,可以用二部或複合形式表達(例如 \p{Present_In=4.0}
),因此 charprop
接受它。但 Any
是 Perl 延伸元件,無法用這種方式表達,因此 charprop
會傳回 undef
。此外,charprop
會傳回 undef
給所有僅限內部的 Perl 延伸元件。
use Unicode::UCD 'charprops_all';
my $%properties_of_A_hash_ref = charprops_all("U+41");
這會傳回一個雜湊的參考,其金鑰為所有不同的 Unicode(非 Perl 延伸元件)屬性,而其值為輸入 「碼位引數」 的這些屬性對應值。
每個金鑰都是屬性名稱,以其最長、最具描述性的形式呈現。值是 「charprop()」 會傳回的值。
此函數在時間和記憶體上都非常耗費。
use Unicode::UCD 'charblock';
my $charblock = charblock(0x41);
my $charblock = charblock(1234);
my $charblock = charblock(0x263a);
my $charblock = charblock("U+263a");
my $range = charblock('Armenian');
使用 「碼位引數」,charblock()
會傳回碼位所屬的 區塊,例如 基本拉丁文
。會傳回舊式區塊名稱(請參閱 「舊式與新式區塊名稱」)。可以使用 「prop_value_aliases()」 函數取得區塊名稱的所有同義詞。
如果碼位未指派,則會傳回如果指派時它所屬的區塊。(如果使用的 Unicode 版本太早而沒有區塊,則所有碼位都被視為在 No_Block
中。)
另請參閱 「區塊與腳本」。
如果提供一個無法成為碼點的參數,charblock()
會嘗試執行相反的動作,並將參數解讀為舊式區塊名稱。在 ASCII 平台上,傳回值是一個包含一個範圍的範圍組:一個單一元素的匿名陣列,其中包含另一個匿名陣列,其第一個元素是區塊中的第一個碼點,而第二個元素是區塊中的最後一個碼點。在 EBCDIC 平台上,前兩個 Unicode 區塊並不連續。其範圍組是包含範圍開頭、範圍結尾碼點配對的清單。你可以使用 "charinrange()" 函式來測試碼點是否在範圍組中。(精確來說,每個範圍組包含第三個陣列元素,在範圍邊界元素之後:舊式區塊名稱。)
如果傳遞給 charblock()
的參數不是已知的區塊,則會傳回 undef
。
use Unicode::UCD 'charscript';
my $charscript = charscript(0x41);
my $charscript = charscript(1234);
my $charscript = charscript("U+263a");
my $range = charscript('Thai');
使用 "碼點參數",charscript()
會傳回碼點所屬的腳本,例如 Latin
、Greek
、Han
。如果碼點未指派或所使用的 Unicode 版本太早而沒有腳本,則此函式會傳回 "Unknown"
。可以使用 "prop_value_aliases()" 函式來取得腳本名稱的所有同義詞。
請注意,Script_Extensions 屬性是 Script 屬性的改良版本,你應該改用它,搭配 "charprop()" 函式。
如果提供一個無法成為碼點的參數,charscript() 會嘗試執行相反的動作,並將參數解讀為腳本名稱。傳回值是一個範圍組:一個包含包含範圍開頭、範圍結尾碼點配對的陣列陣列的匿名陣列。你可以使用 "charinrange()" 函式來測試碼點是否在範圍組中。(精確來說,每個範圍組包含第三個陣列元素,在範圍邊界元素之後:腳本名稱。)
如果 charscript()
參數不是已知的腳本,則會傳回 undef
。
另請參閱 「區塊與腳本」。
use Unicode::UCD 'charblocks';
my $charblocks = charblocks();
charblocks()
會傳回一個雜湊的參考,其中已知的區塊名稱為鍵,而碼點範圍(請參閱 "charblock()")為值。
名稱採用舊式(請參閱 "舊式與新式區塊名稱")。
prop_invmap("block") 可用於以不同類型的資料結構取得相同的資料。
prop_values("Block") 可用於取得所有已知的現代區塊名稱,以清單形式呈現,不含碼點範圍。
另請參閱 「區塊與腳本」。
use Unicode::UCD 'charscripts';
my $charscripts = charscripts();
charscripts()
會傳回一個雜湊的參考,其中已知的腳本名稱為鍵,而碼點範圍(請參閱 "charscript()")為值。
prop_invmap("script") 可用於以不同類型的資料結構取得相同的資料。由於 Script_Extensions 屬性是 Script 屬性的進階版本,因此您應該改用 prop_invmap("scx")。
prop_values("Script")
可用於取得所有已知的腳本名稱,以清單形式呈現,不含碼點範圍。
另請參閱 「區塊與腳本」。
除了使用 \p{Blk=...}
和 \P{Blk=...}
建構外,您還可以測試碼點是否在 "charblock()" 和 "charscript()" 傳回的 範圍 中,或在 "charblocks()" 和 "charscripts()" 傳回的雜湊值中,方法是使用 charinrange()
use Unicode::UCD qw(charscript charinrange);
$range = charscript('Hiragana');
print "looks like hiragana\n" if charinrange($range, $codepoint);
use Unicode::UCD 'general_categories';
my $categories = general_categories();
這會傳回一個雜湊的參考,其中包含簡短的一般類別名稱(例如 Lu
、Nd
、Zs
、S
)作為鍵,而長名稱(例如 UppercaseLetter
、DecimalNumber
、SpaceSeparator
、Symbol
)作為值。如果您需要從長名稱轉換成簡短名稱,則雜湊是可逆的。一般類別是從 "charinfo()" 的 category
鍵傳回的。
"prop_values()" 和 "prop_value_aliases()" 函數可用作此函數的替代方案;第一個函數傳回簡短類別名稱的簡單清單;第二個函數取得給定類別名稱的所有同義詞。
use Unicode::UCD 'bidi_types';
my $categories = bidi_types();
這會傳回一個雜湊的參考,其中包含簡短的雙向 (bidi) 類型名稱 (例如 L
、R
) 作為鍵,以及長名稱 (例如 由左至右
、由右至左
) 作為值。如果您需要從長名稱轉換成簡短名稱,則雜湊是可逆的。bidi 類型是從 "charinfo()" 傳回的,其位於 bidi
鍵之下。建議閱讀 Unicode TR9 以了解各種 bidi 類別的確切含義:http://www.unicode.org/reports/tr9/(截至 Unicode 5.0.0)
"prop_values()" 和 "prop_value_aliases()" 函式可以用作此函式的替代方案;第一個函式傳回簡短 bidi 類型名稱的簡單清單;第二個函式取得給定 bidi 類型名稱的所有同義詞。
警告:Unicode 不建議使用此函式或本節列出的任何替代機制(compexcl()
的文件),除非在 Unicode 正規化演算法的實作中內部使用。您應該直接使用 Unicode::Normalize,而不是使用這些機制。使用這些機制可能會導致結果不盡理想。
use Unicode::UCD 'compexcl';
my $compexcl = compexcl(0x09dc);
如果使用的 Unicode 版本過早,以致於沒有此屬性,則此常式會傳回 undef
。
包含 compexcl()
是為了向後相容,但自 Perl 5.12 和更新的 Unicode 版本開始,對於大多數目的來說,使用下列其中一個函式可能更方便
my $compexcl = chr(0x09dc) =~ /\p{Comp_Ex};
my $compexcl = chr(0x09dc) =~ /\p{Full_Composition_Exclusion};
甚至
my $compexcl = chr(0x09dc) =~ /\p{CE};
my $compexcl = chr(0x09dc) =~ /\p{Composition_Exclusion};
如果 "代碼點引數" 不應由組合正規化產生,則前兩個形式會傳回 true。對於最後兩個形式傳回 true,另外還需要 Unicode 資料庫無法以其他方式確定此事實。
此常式的行為與最後兩個形式相同。也就是說,如果代碼點的分解包含另一個單一代碼點,或者其分解以組合類別為非零的代碼點開頭,則它不會傳回 true。符合這兩個條件之一的代碼點也不應由組合正規化產生,這可能是您應該使用 Full_Composition_Exclusion
屬性的原因,如上所示。
否則,常式會傳回 false。
use Unicode::UCD 'casefold';
my $casefold = casefold(0xDF);
if (defined $casefold) {
my @full_fold_hex = split / /, $casefold->{'full'};
my $full_fold_string =
join "", map {chr(hex($_))} @full_fold_hex;
my @turkic_fold_hex =
split / /, ($casefold->{'turkic'} ne "")
? $casefold->{'turkic'}
: $casefold->{'full'};
my $turkic_fold_string =
join "", map {chr(hex($_))} @turkic_fold_hex;
}
if (defined $casefold && $casefold->{'simple'} ne "") {
my $simple_fold_hex = $casefold->{'simple'};
my $simple_fold_string = chr(hex($simple_fold_hex));
}
這會傳回由"代碼點引數"指定字元的(幾乎)與區域設定無關的大小寫摺疊。(從 Perl v5.16 開始,核心函式 fc()
會比這更快地傳回完整
對應(如下所述),而且適用於整個字串。)
如果輸入代碼點沒有大小寫摺疊,則會傳回 undef
。
如果那個代碼點有大小寫摺疊,則會傳回對應下列欄位的雜湊的參考
輸入原生 "代碼點引數" 以十六進位表示,如有需要,會在前面加上前導零,使其至少包含四個十六進位數字
一個或多個代碼(以空格分隔),依序排列,提供代碼的大小寫摺疊的代碼點。每個代碼至少有四個十六進位數字。
為空,或正好是一個至少有四個十六進位數字的代碼,當呼叫程式無法處理摺疊為多個代碼點的順序時,可以使用這個代碼作為替代大小寫摺疊。如果完整只有一個代碼點,則簡易等於完整。如果沒有為代碼定義單一代碼點摺疊,則簡易為空字串。否則,它是一個較差的,但仍然比完整好一點的替代摺疊。
如果簡易不為空,則與簡易相同;否則,與完整相同。可以將它視為代碼最簡單可能的大小寫摺疊。它主要是為了向後相容性而定義的。
如果最佳可能摺疊是單一代碼點(簡易等於完整等於對應),則為 C
(代表常見
)。如果存在不同的摺疊,簡易和完整(對應等於簡易),則為 S
。如果只有一個完整摺疊(對應等於完整;簡易為空),則為 F
。請注意,這描述了對應的內容。它主要是為了向後相容性而定義的。
對於 3.1 到 3.1.1 含括的 Unicode 版本,狀態也可以是 I
,它與 C
相同,但對於帶點的大寫 I 和不帶點的小寫 i 是特殊狀況
包含任何針對突厥語系的特殊摺疊。對於從 3.2 開始的 Unicode 版本,此欄位為空,除非 code 在突厥語系中具有不同的摺疊,這種情況下它會是一個或多個(以空格分隔)的代碼,依序取用這些代碼會提供這些語言中 code 的大小寫摺疊的代碼點。每個代碼至少有四個十六進位數字。請注意,此摺疊不會在沒有額外處理的情況下維持正規等價性。
對於 3.1 到 3.1.1 含括的 Unicode 版本,此欄位為空,除非針對突厥語系有特殊摺疊,這種情況下 status 為 I
,且 mapping、full、simple 和 turkic 全部相等。
想要完整通用性和最佳摺疊結果的程式應使用 full 欄位中包含的摺疊。但請注意,某些代碼點的摺疊會是多個代碼點的序列。
無法處理摺疊對應為多個代碼點的程式可以使用 simple 欄位中包含的摺疊,但會犧牲一些通用性。在 Unicode 5.1 中,約有 7% 的定義摺疊沒有單一代碼點摺疊。
mapping 和 status 欄位提供給現有程式做為向後相容性。它們包含的值與此函式的先前版本相同。
區域設定並非完全獨立。當區域設定為突厥語系時,turkic 欄位包含要使用的結果。
有關大小寫對應的更多資訊,請參閱 http://www.unicode.org/reports/tr21
use Unicode::UCD 'all_casefolds';
my $all_folds_ref = all_casefolds();
foreach my $char_with_casefold (sort { $a <=> $b }
keys %$all_folds_ref)
{
printf "%04X:", $char_with_casefold;
my $casefold = $all_folds_ref->{$char_with_casefold};
# Get folds for $char_with_casefold
my @full_fold_hex = split / /, $casefold->{'full'};
my $full_fold_string =
join "", map {chr(hex($_))} @full_fold_hex;
print " full=", join " ", @full_fold_hex;
my @turkic_fold_hex =
split / /, ($casefold->{'turkic'} ne "")
? $casefold->{'turkic'}
: $casefold->{'full'};
my $turkic_fold_string =
join "", map {chr(hex($_))} @turkic_fold_hex;
print "; turkic=", join " ", @turkic_fold_hex;
if (defined $casefold && $casefold->{'simple'} ne "") {
my $simple_fold_hex = $casefold->{'simple'};
my $simple_fold_string = chr(hex($simple_fold_hex));
print "; simple=$simple_fold_hex";
}
print "\n";
}
這會以對雜湊的參考形式傳回 Unicode 目前版本中的所有大小寫摺疊。雜湊的每個金鑰都是具有大小寫摺疊(摺疊為非自身)的 Unicode 字元的十進位表示。分號的大小寫摺疊為自身,因此它不在雜湊中;小寫「a」也是如此,但大寫「A」有一個項目。每個金鑰的雜湊值是另一個雜湊,與 "casefold()" 在以該代碼點作為其引數呼叫時傳回的值相同。因此,值 all_casefolds()->{ord("A")}'
等於 casefold(ord("A"))
;
use Unicode::UCD 'casespec';
my $casespec = casespec(0xFB00);
這會傳回 "代碼點引數" 的可能與區域設定相關的大小寫對應。對應可能長於單一代碼點("charinfo()" 傳回的基本 Unicode 大小寫對應永遠不會這樣)。
如果沒有 「代碼點參數」 的大小寫對應,或者所有三個可能的對應(小寫、標題 和 大寫)都產生單一代碼點,而且與語言環境無關且無條件,則會傳回 undef
(表示代碼點的大小寫對應(如果有)是由 「charinfo()」 傳回的)。
否則,會傳回一個參考,提供一個雜湊,用於提供對應(或一個雜湊的雜湊的參考,說明如下),其中包含下列鍵及其意義
底層雜湊中的鍵及其值的意義為
輸入原生 "代碼點引數" 以十六進位表示,如有需要,會在前面加上前導零,使其至少包含四個十六進位數字
一個或多個代碼(以空格分隔),依序排列,提供 代碼 的小寫代碼點。每個代碼至少有四個十六進位數字。
一個或多個代碼(以空格分隔),依序排列,提供 代碼 的標題大小寫代碼點。每個代碼至少有四個十六進位數字。
一個或多個代碼(以空格分隔),依序排列,提供 代碼 的大寫代碼點。每個代碼至少有四個十六進位數字。
對應有效的條件。如果為 undef
,則對應永遠有效。定義時,這個欄位是條件清單,所有條件都必須為 true,對應才會有效。清單包含一個或多個語言環境(請見下方)和/或內容(在下一段說明),以空格分隔。(除了用於分隔元素之外,空格都應忽略。)條件清單中的大小寫區分無關緊要。以「NON_」為前綴的條件表示條件的否定。
內容是 Unicode 標準中定義的其中之一。對於 Unicode 5.1,它們定義在第 3.13 節 預設大小寫運算
,可於 http://www.unicode.org/versions/Unicode5.1.0/ 取得。這些是針對內容敏感的大小寫處理。
上面說明的雜湊會傳回給與語言環境無關的大小寫處理,其中至少一個對應的長度大於 1。如果傳回 undef
,則代碼點可能有對應,但如果有,則所有對應的長度都為 1,而且會由 「charinfo()」 傳回。請注意,當這個函數傳回值時,會傳回代碼點的完整對應集,即使長度為 1 的對應也一樣。
如果只有在特定地區適用的額外大小寫規則,則會在傳回的雜湊中定義每個規則的額外金鑰。每個此類金鑰都會是其地區名稱,定義為 2 個字母的 ISO 3166 國家/地區代碼,後接底線 (_) 和 2 個字母的 ISO 語言代碼(後接底線 (_) 和變體代碼)。您可以找到所有可能的地區清單,請參閱 Locale::Country 和 Locale::Language。(在 Unicode 6.0 中,此函數傳回的唯一地區是 lt
、tr
和 az
。)
每個地區金鑰都是對具有上述格式的雜湊的參照,並提供該特定地區的大小寫規則,在該地區時,這些規則優先於與地區無關的規則。
如果碼點的唯一大小寫取決於地區,則傳回的雜湊不會有任何基本金鑰,例如 code
、upper
等,但只會包含地區金鑰。
如需有關大小寫對應的更多資訊,請參閱 http://www.unicode.org/reports/tr21/
use Unicode::UCD 'namedseq';
my $namedseq = namedseq("KATAKANA LETTER AINU P");
my @namedseq = namedseq("KATAKANA LETTER AINU P");
my %namedseq = namedseq();
如果在標量內容中使用單一引數,則傳回由命名序列碼點組成的字串,或如果沒有該名稱的命名序列,則傳回 undef
。如果在清單內容中使用單一引數,則傳回碼點序數的清單。
如果在清單內容中不使用任何引數,則傳回一個雜湊,其中所有命名序列的名稱作為金鑰,其序列作為字串作為值。否則,它會傳回 undef
或空清單,具體取決於內容。
此函數僅對官方核准(非臨時)命名序列執行作業。
請注意,自 Perl 5.14 起,\N{KATAKANA LETTER AINU P}
會將命名序列插入雙引號字串中,而 charnames::string_vianame("KATAKANA LETTER AINU P")
會傳回此函數傳回的相同字串,但也會對非命名序列的字元名稱執行作業,而您不必知道哪些是哪些。請參閱 charnames。
use Unicode::UCD 'num';
my $val = num("123");
my $one_quarter = num("\N{VULGAR FRACTION ONE QUARTER}");
my $val = num("12a", \$valid_length); # $valid_length contains 2
num()
傳回輸入 Unicode 字串的數字值;或如果它認為整個字串沒有完全有效、安全的數字值,則傳回 undef
。如果使用可選的第二個參數(對標量的參照)呼叫,則 num()
會將標量設定為任何有效初始子字串的長度;或如果沒有,則設定為 0。
如果字串長度僅有一個字元,則會傳回 Unicode 數值(如果有的話),否則傳回 undef
。如果傳遞了選用的純量參考,如果傳回值有效,則會設定為 1;如果傳回值是 undef
,則會設定為 0。請注意,傳回的數值不必是整數。例如,num("\N{TIBETAN DIGIT HALF ZERO}")
會傳回 -0.5。
如果字串長度超過一個字元,則會傳回 undef
,除非所有字元都是小數位元(亦即,會符合 \d+
),且來自相同的文字系統。例如,如果您將 ASCII '0' 和孟加拉語 '3' 混在一起,它們不會被視為有效的數字,且會傳回 undef
。另一個限制是,所有位元都必須具有相同的形式。半形位元與全形位元混在一起會傳回 undef
。阿拉伯文字系統有兩組位元;num
會傳回 undef
,除非字串中的所有位元都來自同一組。在所有情況下,選用的純量參考參數會設定為任何有效的位元初始子字串的長度;因此,如果主要傳回值不是 undef
,則會設定為整個字串長度。
num
偏向安全,可能有一些它無法辨識的有效小數位元字串。請注意,Unicode 定義了許多「位元」字元,這些字元並非「小數位元」字元。「小數位元」具有位置值的特性,亦即,有一個單位位置、一個 10 的位置、一個 100 的位置,等等,而且它們在 Unicode 中排列成 10 個連續碼點的區塊。例如,中文位元不在此類連續區塊中,因此 Unicode 不將它們視為小數位元,而僅視為位元,所以 \d
無法與它們相符。包含這些位元之一的單字元字串會由 num
傳回其小數值,但僅包含這些位元的任何較長字串會傳回 undef
。
多個上標和下標的字串不會被辨識為數字。您可以使用 Unicode::Normalize 中的任何相容性分解將這些字元轉換為位元,然後對結果呼叫 num
。
use Unicode::UCD 'prop_aliases';
my ($short_name, $full_name, @other_names) = prop_aliases("space");
my $same_full_name = prop_aliases("Space"); # Scalar context
my ($same_short_name) = prop_aliases("Space"); # gets 0th element
print "The full name is $full_name\n";
print "The short name is $short_name\n";
print "The other aliases are: ", join(", ", @other_names), "\n";
prints:
The full name is White_Space
The short name is WSpace
The other aliases are: Space
大部分 Unicode 屬性都有多個同義名稱。通常,至少有一個簡短名稱,方便輸入,還有一個長名稱,更完整地描述屬性,因此更容易理解。
如果您知道 Unicode 屬性的其中一個名稱,您可以使用 prop_aliases
找出長名稱(在標量上下文中呼叫時),或找出所有名稱的清單,大致上以簡短名稱在第 0 個元素、長名稱在下一元素,以及任何其他同義詞在剩餘元素中,沒有特定順序。
長名稱以美觀的大寫形式傳回,適合列印。
輸入參數名稱是寬鬆配對的,這表示空白、連字號和底線會被忽略(除了 "L_"
中舊式繼承的尾隨底線,最好寫成 "LC"
,而且兩個都表示 General_Category=Cased Letter
)。
如果名稱未知,則傳回 undef
(或在清單上下文中傳回空清單)。請注意,Perl 通常在正規表示式中辨識屬性名稱,並加上一個選擇性的 "Is_"
(有或沒有底線)前綴,例如 \p{isgc=punct}
。此函式不會辨識輸入中的那些,傳回 undef
。它們也不會包含在輸出中作為可能的同義詞。
prop_aliases
了解 Unicode 屬性的 Perl 延伸,例如 Any
和 XPosixAlpha
,以及 Unicode 屬性的單一形式等效項,例如 XDigit
、Greek
、In_Greek
和 Is_Greek
。最後一個範例說明 "Is_"
前綴會被辨識為這些延伸;它需要用來解決歧義。例如,prop_aliases('lc')
傳回清單 (lc, Lowercase_Mapping)
,但 prop_aliases('islc')
傳回 (Is_LC, Cased_Letter)
。這是因為 islc
是 Perl 延伸,是 General_Category=Cased Letter
的簡寫。傳回的 Perl 延伸清單不會包含 "Is_"
前綴(無論輸入有沒有),除非需要解決歧義,如 "islc"
範例所示,傳回的清單有一個元素包含 "Is_"
,另一個沒有。
反過來也是有可能的:prop_aliases('isc')
傳回清單 (isc, ISO_Comment)
;而 prop_aliases('c')
傳回 (C, Other)
(後者是 Perl 延伸,表示 General_Category=Other
。 perluniprops 中的「可透過 Unicode::UCD 存取的屬性」 列出可用的形式,包括哪些形式不建議使用。
這些不建議使用的形式被接受為 prop_aliases
的輸入,但不會在清單中傳回。prop_aliases('isL&')
和 prop_aliases('isL_')
是 "Is_LC"
的舊同義詞,不應在新的程式碼中使用,這是這方面的範例。這兩個都傳回 (Is_LC, Cased_Letter)
。因此,這個函數允許您採用不建議使用的形式,並找出其可接受的替代方案。單一形式區塊屬性的等價性也是如此。只有以 "In_"
開頭的形式不被禁止;如果您傳遞 prop_aliases
一個不建議使用的形式,您將會取得以 "In_"
開頭的等價形式。否則,它看起來像一個新式區塊名稱(請參閱 "舊式與新式區塊名稱")。
prop_aliases
不知道任何使用者定義的屬性,如果使用其中一個屬性呼叫,將會傳回 undef
。Perl 內部屬性也是如此,但「Perl_Decimal_Digit」除外,它知道這個屬性(並在 "prop_invmap()" 中記載於下方)。
use Unicode::UCD 'prop_values';
print "AHex values are: ", join(", ", prop_values("AHex")),
"\n";
prints:
AHex values are: N, Y
一些 Unicode 屬性具有受限的一組合法值。例如,所有二元屬性僅限於 true
或 false
;而只有數十個可能的通用類別。使用 prop_values
找出給定的屬性是否為其中之一,如果是,則取得值清單
print join ", ", prop_values("NFC_Quick_Check");
prints:
M, N, Y
如果屬性沒有這種受限的組,則傳回 undef
。
每個可能的值通常有幾個同義詞。使用 "prop_value_aliases()" 存取這些同義詞。
在輸入屬性名稱中會忽略大小寫、空白、連字號和底線(舊式已棄用通用類別屬性值 "L_"
中的尾隨底線除外,建議寫成 "LC"
)。
如果屬性名稱未知,則傳回 undef
。請注意,Perl 通常會在正規表示式中辨識屬性名稱,並加上一個選用的 "Is_"
(有或沒有底線)作為前綴,例如 \p{isgc=punct}
。這個函數不會在屬性參數中辨識這些,傳回 undef
。
對於區塊屬性,會傳回新式區塊名稱(請參閱 "舊式與新式區塊名稱")。
prop_values
不知道任何使用者定義的屬性,如果使用其中一個屬性呼叫,將會傳回 undef
。
use Unicode::UCD 'prop_value_aliases';
my ($short_name, $full_name, @other_names)
= prop_value_aliases("Gc", "Punct");
my $same_full_name = prop_value_aliases("Gc", "P"); # Scalar cntxt
my ($same_short_name) = prop_value_aliases("Gc", "P"); # gets 0th
# element
print "The full name is $full_name\n";
print "The short name is $short_name\n";
print "The other aliases are: ", join(", ", @other_names), "\n";
prints:
The full name is Punctuation
The short name is P
The other aliases are: Punct
有些 Unicode 屬性具有受限的合法值集合。例如,所有二進位屬性僅限於 true
或 false
;而只有數十個可能的通用類別。
您可以使用 "prop_values()" 來找出給定的屬性是否為具有受限值集合的屬性,如果是,則找出這些值是什麼。但通常每個值實際上都有幾個同義詞。例如,在 Unicode 二進位屬性中,真可以用任何字串「Y」、「Yes」、「T」或「True」表示;通用類別「標點符號」可以用該字串、或「Punct」、或僅「P」表示。
與屬性名稱類似,每個此類屬性值通常至少有一個簡稱和一個全稱。如果您知道屬性值的任何名稱(您可以透過 "prop_values()" 取得),您可以使用 prop_value_aliases
() 來取得全稱(在標量內容中呼叫時),或所有名稱的清單,其中簡稱在第 0 個元素中,全稱在下一元素中,任何其他同義詞在剩餘元素中,順序不特定,但任何全數字同義詞將在最後。
長名稱以美觀的大寫形式傳回,適合列印。
在輸入參數中會忽略大小寫、空白、連字號和底線(除了舊格式中已納入通用類別屬性值 "L_"
中的尾隨底線,最好寫成 "LC"
)。
如果任一名稱未知,則傳回 undef
。請注意,Perl 通常會在正規表示式中識別屬性名稱,並加上一個選用的 "Is_
"(有或沒有底線)前綴,例如 \p{isgc=punct}
。此函式不會在屬性參數中識別這些,傳回 undef
。
如果呼叫時使用的屬性沒有其值的同義詞,則傳回輸入值,可能會用大寫和小寫字母及底線正規化,但不必檢查輸入值是否有效。
對於區塊屬性,會傳回新式區塊名稱(請參閱 "舊式與新式區塊名稱")。
若要找出單一形式的同義詞,例如 \p{Any}
,請改用 "prop_aliases()"。
prop_value_aliases
不知道任何使用者定義的屬性,如果呼叫其中一個屬性,將會傳回 undef
。
prop_invlist
傳回反轉清單(如下所述),定義輸入參數字串所提供的二進位 Unicode 屬性(或「屬性=值」配對)的所有碼點
use feature 'say';
use Unicode::UCD 'prop_invlist';
say join ", ", prop_invlist("Any");
prints:
0, 1114112
如果輸入未知,則在純量內容傳回 undef
;在清單內容傳回空清單。如果輸入已知,則在純量內容呼叫時傳回清單中的元素數目。
perluniprops 提供此函式接受的屬性清單,以及它們所有可能的格式(包括選用的「Is_」前綴)。(但此函式不接受任何 Perl 內部屬性,其中一些列於此處。)此函式使用與正規表示式相同的寬鬆或更嚴格的比對規則來解析輸入屬性的名稱。這些也指定在 perluniprops 中。使用「屬性=值」格式的範例如下
say join ", ", prop_invlist("Script_Extensions=Shavian");
prints:
66640, 66688
say join ", ", prop_invlist("ASCII_Hex_Digit=No");
prints:
0, 48, 58, 65, 71, 97, 103
say join ", ", prop_invlist("ASCII_Hex_Digit=Yes");
prints:
48, 58, 65, 71, 97, 103
反轉清單是指定 Unicode 屬性值定義的精簡方式。清單中的第 0 個項目是具有屬性值的最低碼點。下一個項目(項目 [1])是超出該碼點且沒有屬性值的最低碼點。而超出該碼點且具有屬性值的最低碼點是下一個項目 ([2]),以此類推。換句話說,清單中的每個元素都會提供具有屬性值(對於偶數元素)或沒有屬性值(對於奇數元素)的範圍開頭。此資料結構的名稱源自於清單中的每個元素都會切換(或反轉)對應範圍是否在清單中。
在上述最後一個範例中,第一個 ASCII 十六進位數字是碼點 48,字元「0」,從它到 57(「9」)的所有碼點都是 ASCII 十六進位數字。碼點 58 到 64 不是,但 65(「A」)到 70(「F」)是,97(「a」)到 102(「f」)也是。103 開始一個沒有 ASCII 十六進位數字的碼點範圍。該範圍延伸到無限大,在您的電腦中可以在變數 $Unicode::UCD::MAX_CP
中找到。(此變數接近 Perl 在您的平台上能達到的無限大,而且可能太高而無法執行某些作業;您可能希望為您的目的使用較小的數字。)
請注意,此函式傳回的倒置列表可能包含非 Unicode 編碼點,也就是大於 0x10FFFF 的任何內容。Unicode 屬性未定義於此類編碼點。您可能希望變更輸出,以不包含這些內容。只要在非空傳回列表的結尾加上 0x110000(如果它不是該值);如果是,則移除該值;例如
my @list = prop_invlist("foo");
if (@list) {
if ($list[-1] == 0x110000) {
pop @list; # Defeat the turning on for above Unicode
}
else {
push @list, 0x110000; # Turn off for above Unicode
}
}
將倒置列表擴充為具有屬性值的全部編碼點列表是一件簡單的事
my @invlist = prop_invlist($property_name);
die "empty" unless @invlist;
my @full_list;
for (my $i = 0; $i < @invlist; $i += 2) {
my $upper = ($i + 1) < @invlist
? $invlist[$i+1] - 1 # In range
: $Unicode::UCD::MAX_CP; # To infinity.
for my $j ($invlist[$i] .. $upper) {
push @full_list, $j;
}
}
prop_invlist
不知道任何使用者定義或 Perl 內部專屬屬性,如果使用其中一個屬性呼叫,它將傳回 undef
。
"search_invlist()" 函式用於在倒置列表中尋找編碼點。
use Unicode::UCD 'prop_invmap';
my ($list_ref, $map_ref, $format, $default)
= prop_invmap("General Category");
prop_invmap
用於取得屬性的完整對應定義,以倒置對應的形式。倒置對應包含兩個平行陣列。一個是有序的編碼點列表,用於標示範圍開頭,另一個提供對應範圍內所有編碼點的值(或對應)。
prop_invmap
使用所需屬性的名稱呼叫。名稱是寬鬆比對,表示大小寫、空白、連字號和底線的差異沒有意義(舊式祖父條款屬性 "L_"
中的尾隨底線除外,建議寫成 "LC"
,甚至更好的是 "Gc=LC"
)。
許多 Unicode 屬性有多個名稱(或別名)。prop_invmap
了解所有這些,包括 Perl 對它們的擴充。模糊性會如上文 "prop_aliases()" 所述解決(但如果屬性同時具有完整對應和二進位 Y
/N
對應,則指定屬性名稱加上 "is"
前綴會傳回二進位對應)。Perl 內部屬性「Perl_Decimal_Digit」,說明如下,也接受。如果屬性名稱不明,則傳回空列表。請參閱 "perluniprops 中可透過 Unicode::UCD 存取的屬性",以了解此函式可接受的輸入屬性。
除了在列表內容中呼叫此函式外,其他情況都是致命錯誤。
除了形成倒置對應的兩個陣列外,prop_invmap
還傳回其他兩個值;一個是提供對應陣列條目格式的一些詳細資料的純量;另一個是預設值,用於格式名稱開頭為字母 "a"
的對應,如 以下小節中所述;以及用於特殊目的,例如轉換為其他資料結構,如本主要部分結尾所述。
這表示 prop_invmap
傳回 4 個元素的列表。例如,
my ($blocks_ranges_ref, $blocks_maps_ref, $format, $default)
= prop_invmap("Block");
在此呼叫中,兩個陣列會依下列方式填入(針對 Unicode 6.0)
Index @blocks_ranges @blocks_maps
0 0x0000 Basic Latin
1 0x0080 Latin-1 Supplement
2 0x0100 Latin Extended-A
3 0x0180 Latin Extended-B
4 0x0250 IPA Extensions
5 0x02B0 Spacing Modifier Letters
6 0x0300 Combining Diacritical Marks
7 0x0370 Greek and Coptic
8 0x0400 Cyrillic
...
233 0x2B820 No_Block
234 0x2F800 CJK Compatibility Ideographs Supplement
235 0x2FA20 No_Block
236 0xE0000 Tags
237 0xE0080 No_Block
238 0xE0100 Variation Selectors Supplement
239 0xE01F0 No_Block
240 0xF0000 Supplementary Private Use Area-A
241 0x100000 Supplementary Private Use Area-B
242 0x110000 No_Block
第一行(索引 [0])表示碼點 0 的值為「基本拉丁文」。第二行 @blocks_ranges 欄中的「0x0080」項目表示第一行「基本拉丁文」的值延伸至 0 到 0x0080(不包含)範圍內的所有碼點,也就是到 127 為止。換句話說,0 到 127 的碼點都在「基本拉丁文」區塊中。類似地,0x0080 到(不包含)0x0100 範圍內的所有碼點都在名為「拉丁文-1 補充」的區塊中,依此類推。(請注意,回傳值是舊式區塊名稱;請參閱 "舊式與新式區塊名稱")。
最後一行(索引 [242])表示所有超過合法 Unicode 最大碼點的碼點的值為「No_Block」,這是 Unicode 用來表示不存在區塊的術語。
這些陣列完全指定所有可能碼點的對應。此函數回傳的反轉對應中最後一個元素永遠會是包含所有非合法 Unicode 碼點的範圍,但可以在平台上表達。(也就是說,從 0x110000 開始,這是超過合法 Unicode 最大值的碼點,延伸到無限大。)該範圍的值會與任何典型未指派碼點對於指定屬性的值相同。(某些未指派碼點並非「典型」;例如非字元碼點,或在從右到左書寫的區塊中的碼點。超過 Unicode 範圍的值並非根據這些非典型碼點。)可以論證,與其將這些當作未指派 Unicode 碼點處理,此範圍的值應該為 undef
。如果您願意,可以相應地變更回傳的陣列。
幾乎所有屬性的對應都是應按原樣解釋的簡單純量。這些值是 Unicode 提供的資料檔中所提供的,可能在大小寫和屬性值所給的同義詞方面不一致。可以使用 "prop_value_aliases()" 函數標準化結果。
簡單的標量對應有例外。有些屬性在對應清單中有一些元素本身是標量的清單;而且會傳回一些特殊字串,不可照樣解釋。傳回的四個元素清單的元素 [2](在上述範例中放入 $format
)會告訴您對應是否有這些特殊元素,如下所示
s
表示對應陣列的所有元素都是簡單標量,沒有特殊元素。幾乎所有屬性都像這樣,例如上述的 block
範例。
sl
表示對應陣列元素中有一些具有 "s"
給定的形式,而其餘的是標量清單。例如,以下是呼叫 prop_invmap
() 並使用「Script Extensions」屬性的輸出部分
@scripts_ranges @scripts_maps
...
0x0953 Devanagari
0x0964 [ Bengali, Devanagari, Gurumukhi, Oriya ]
0x0966 Devanagari
0x0970 Common
在此,碼點 0x964 和 0x965 都用於孟加拉文、天城文、古木基文和奧里亞文,但沒有其他文字。
Name_Alias 屬性也有這種形式。但每個標量包含兩個組成部分:1) 名稱,以及 2) 這是哪種類型的別名。它們以冒號和空格分隔。在 Unicode 6.1 中,有數種別名類型
correction
表示名稱是原始名稱的更正形式(對應相同的碼點,且仍然有效)。
control
為控制字元新增一個新名稱。
alternate
是字元的備用名稱
figment
是已記錄但從未出現在任何實際標準中的字元名稱。
abbreviation
是字元的常見縮寫
清單的順序(大致上)是優先名稱出現在較不優先的名稱之前。
例如,
@aliases_ranges @alias_maps
...
0x009E [ 'PRIVACY MESSAGE: control', 'PM: abbreviation' ]
0x009F [ 'APPLICATION PROGRAM COMMAND: control',
'APC: abbreviation'
]
0x00A0 'NBSP: abbreviation'
0x00A1 ""
0x00AD 'SHY: abbreviation'
0x00AE ""
0x01A2 'LATIN CAPITAL LETTER GHA: correction'
0x01A3 'LATIN SMALL LETTER GHA: correction'
0x01A4 ""
...
對應至空字串表示未定義碼點的別名。
a
類似於 "s"
,因為所有映射陣列元素都是純量,但這裡限制為全部都是整數,且有些必須調整(因此命名為 "a"
)才能得到正確的結果。例如,在
my ($uppers_ranges_ref, $uppers_maps_ref, $format, $default)
= prop_invmap("Simple_Uppercase_Mapping");
傳回的陣列看起來像這樣
@$uppers_ranges_ref @$uppers_maps_ref Note
0 0
97 65 'a' maps to 'A', b => B ...
123 0
181 924 MICRO SIGN => Greek Cap MU
182 0
...
且 $default
為 0。
從第二行開始。它表示碼點 97 的大寫為 65;或者 uc("a")
== "A"。但這行是針對碼點 97 到 122 的整個範圍。若要取得此範圍內任何碼點的對應,請取它與範圍起始碼點的偏移量,並將其加到該第一個碼點的對應。因此,122 ("z") 的對應是取 122 與 97 的偏移量 (=25),並將其加到 65,得到 90 ("Z")。介於其間的所有內容亦同。
需要這個簡單的調整,才能讓傳回的陣列比其他情況小很多,最多可達 10 倍,加快搜尋速度。
對應到 $default
、"0"
的範圍行為略有不同。對於這些範圍,每個碼點都對應到它自己。因此,在範例的第一行中,ord(uc(chr(0)))
為 0,ord(uc(chr(1)))
為 1,.. ord(uc(chr(96)))
為 96。
al
表示部分映射陣列元素具有 "a"
給定的形式,其餘部分是有序碼點清單。例如,在
my ($uppers_ranges_ref, $uppers_maps_ref, $format, $default)
= prop_invmap("Uppercase_Mapping");
傳回的陣列看起來像這樣
@$uppers_ranges_ref @$uppers_maps_ref
0 0
97 65
123 0
181 924
182 0
...
0x0149 [ 0x02BC 0x004E ]
0x014A 0
0x014B 330
...
這是完整的 Uppercase_Mapping 屬性(與格式 "a"
範例中給定的 Simple_Uppercase_Mapping 相反)。在顯示的範圍中,兩者之間唯一的差異是碼點 0x0149(帶有撇號的拉丁小寫字母 N)對應到兩個字元的字串,0x02BC(修飾符號撇號)後接 0x004E(拉丁大寫字母 N)。
不需要對參照陣列的項目進行調整;每個此類項目在其範圍內只有一個元素,因此偏移量永遠為 0。
針對此格式傳回的清單中,第四個(索引 [3])元素($default
)為 0。
ae
這就像 "a"
,但有些元素為空字串,不應調整。prop_invmap
可存取的內部 Perl 屬性為此類型:「Perl_Decimal_Digit」傳回反轉對應,提供 Unicode 十進位數字字元所表示的數字值。不表示十進位數字的字元會對應到空字串,如下所示
@digits @values
0x0000 ""
0x0030 0
0x003A: ""
0x0660: 0
0x066A: ""
0x06F0: 0
0x06FA: ""
0x07C0: 0
0x07CA: ""
0x0966: 0
...
這表示 0 到 0x2F 的碼點不表示十進位數字;碼點 0x30(數字零)表示 0;碼點 0x31(數字一)表示 0+1-0 = 1;... 碼點 0x39(數字九)表示 0+9-0 = 9;... 碼點 0x3A 到 0x65F 不表示十進位數字;0x660(阿拉伯印度數字零)表示 0;... 0x07C1(NKO 數字一)表示 0+1-0 = 1 ...
此格式傳回清單中的第四個(索引 [3])元素($default
)為空字串。
ale
結合 "al"
類型和 "ae"
類型。對應陣列元素有些具有 "al"
提供的形式,其餘為空字串。NFKC_Casefold
屬性具有此形式。範例切片為
@$ranges_ref @$maps_ref Note
...
0x00AA 97 FEMININE ORDINAL INDICATOR => 'a'
0x00AB 0
0x00AD SOFT HYPHEN => ""
0x00AE 0
0x00AF [ 0x0020, 0x0304 ] MACRON => SPACE . COMBINING MACRON
0x00B0 0
...
針對此格式傳回的清單中,第四個(索引 [3])元素($default
)為 0。
ar
表示對應陣列的所有元素都是有理數或字串 "NaN"
,表示「非數字」。有理數為整數,或兩個整數以斜線("/"
)分隔。第二個整數表示斜線所暗示的除法的分母,且實際上總是為正數,因此保證不為 0 且不帶正負號。當元素為純整數(沒有斜線)時,可能需要透過加入偏移量來調整以取得正確值,就像其他 "a"
屬性一樣。分數不需要調整,因為保證範圍只有一個元素,因此偏移量永遠為 0。
如果您想將傳回的對應轉換為純量數字,可以使用類似以下的內容
my ($invlist_ref, $invmap_ref, $format) = prop_invmap($property);
if ($format && $format eq "ar") {
map { $_ = eval $_ if $_ ne 'NaN' } @$map_ref;
}
以下是格式為 "ar"
的「Nv」屬性輸出的部分條目。
@numerics_ranges @numerics_maps Note
0x00 "NaN"
0x30 0 DIGIT 0 .. DIGIT 9
0x3A "NaN"
0xB2 2 SUPERSCRIPTs 2 and 3
0xB4 "NaN"
0xB9 1 SUPERSCRIPT 1
0xBA "NaN"
0xBC 1/4 VULGAR FRACTION 1/4
0xBD 1/2 VULGAR FRACTION 1/2
0xBE 3/4 VULGAR FRACTION 3/4
0xBF "NaN"
0x660 0 ARABIC-INDIC DIGIT ZERO .. NINE
0x66A "NaN"
此格式傳回的清單中,第四個 (索引 [3]) 元素 ($default
) 為 "NaN"
。
n
表示名稱屬性。映射陣列的所有元素都是簡單的純量,但有些元素包含特殊字串,需要進一步處理才能取得實際名稱。
例如
CJK UNIFIED IDEOGRAPH-<code point>
表示碼點的名稱為「CJK UNIFIED IDEOGRAPH-」,後面加上碼點 (以十六進位表示),例如「CJK UNIFIED IDEOGRAPH-3403」(對於 CJK COMPATIBILITY IDEOGRAPH-<碼點>
也是如此)。
此外,像
<hangul syllable>
這樣的條目表示名稱是演算法計算出來的。這很容易透過 charnames 中的函式 "charnames::viacode(code)" 來完成。
請注意,對於控制字元 (Gc=cc
),Unicode 的資料檔有字串「<control>
」,但這些字元的實際名稱是空字串。此函式會傳回那個實際名稱,也就是空字串。(這些字元有名稱,但它們被視為別名,而不是名稱屬性名稱,且包含在 Name_Alias
屬性中。)
ad
表示 Decomposition_Mapping 屬性。此屬性類似於 "al"
屬性,但其中一個純量元素的格式為
<hangul syllable>
這表示此條目應替換為分解為所有碼點的分解,其分解是由演算法計算出來的。(它們目前全部都在一個範圍內,而且範圍外不太可能再新增到 Unicode 中;"n"
格式有相同的條目。) 這些分解可以透過函式 Unicode::Normalize::NFD() 產生。
請注意,此映射是 Unicode 資料檔中指定的映射,而且若要取得最終分解,可能需要遞迴套用。事實上,Unicode 不鼓勵使用此屬性,除非是在 Unicode 正規化演算法的實作中內部使用。
針對此格式傳回的清單中,第四個(索引 [3])元素($default
)為 0。
請注意,格式開頭的字母為「a」當且僅當它所屬的屬性需要透過在多元素範圍中加入偏移量來進行調整。對於所有這些屬性,只有當映射為整數的純量時,才應調整條目。也就是說,它必須符合正規表示法
/ ^ -? \d+ $ /xa
此外,範圍中的第一個元素永遠不需要調整,因為調整只會加上 0。
可以使用 "search_invlist()" 提供的二元搜尋,快速在反轉清單中找到碼點,進而找到其對應的映射。
此函數所回傳的四個元素清單中最後的第四個元素(索引 [3],在「區塊」範例中指定給 $default
)會與 "a"
格式類型一起使用;對於想要將回傳的反轉對應資料結構轉換成其他資料結構(例如雜湊)的應用程式來說,這也可能很有用。它會提供屬性中大部分編碼點對應的對應。如果您建立一個慣例,將資料結構中未明確列出的任何編碼點對應到這個值,您就有可能讓資料結構變小很多。當您從此函數回傳的資料結構建構自己的資料結構時,只要忽略對應到這個值的那些範圍即可。例如,若要轉換成可由 "charinrange()" 搜尋的資料結構,您可以遵循這個不需要調整的屬性食譜
my ($list_ref, $map_ref, $format, $default) = prop_invmap($property);
my @range_list;
# Look at each element in the list, but the -2 is needed because we
# look at $i+1 in the loop, and the final element is guaranteed to map
# to $default by prop_invmap(), so we would skip it anyway.
for my $i (0 .. @$list_ref - 2) {
next if $map_ref->[$i] eq $default;
push @range_list, [ $list_ref->[$i],
$list_ref->[$i+1],
$map_ref->[$i]
];
}
print charinrange(\@range_list, $code_point), "\n";
這樣一來,如果 charinrange()
的輸入編碼點對應到 $default
,charinrange()
會回傳 undef
。您可以省略 next
陳述式並在迴圈後新增一行來處理反轉對應的最後一個元素,以避免發生這種情況。
類似地,這個食譜也可以用於需要調整的屬性
for my $i (0 .. @$list_ref - 2) {
next if $map_ref->[$i] eq $default;
# prop_invmap() guarantees that if the mapping is to an array, the
# range has just one element, so no need to worry about adjustments.
if (ref $map_ref->[$i]) {
push @range_list,
[ $list_ref->[$i], $list_ref->[$i], $map_ref->[$i] ];
}
else { # Otherwise each element is actually mapped to a separate
# value, so the range has to be split into single code point
# ranges.
my $adjustment = 0;
# For each code point that gets mapped to something...
for my $j ($list_ref->[$i] .. $list_ref->[$i+1] -1 ) {
# ... add a range consisting of just it mapping to the
# original plus the adjustment, which is incremented for the
# next time through the loop, as the offset increases by 1
# for each element in the range
push @range_list,
[ $j, $j, $map_ref->[$i] + $adjustment++ ];
}
}
}
請注意,針對 Case_Folding
和 Simple_Case_Folding
屬性回傳的反轉對應不包含突厥語系的對應。請針對這些屬性使用 "casefold()"。
prop_invmap
不認識任何使用者定義的屬性,如果呼叫時帶有一個使用者定義的屬性,它會回傳 undef
。
Perl 延伸屬性(例如 Any
和 Greek
)的回傳值有點令人誤解。這些值不是 "Y"
就是 "N
"。所有 Unicode 屬性都是二分的,因此您實際上可以在 Perl 正規表示式中針對這些屬性使用 "Y"
或 "N
",例如 qr/\p{ID_Start=Y/}
或 qr/\p{Upper=N/}
。但是 Perl 延伸並沒有這樣指定,只會像 /qr/\p{Any}
等指定。您實際上無法在其中使用 "Y"
和 "N
"。
建議您使用提供的函數,而非直接從檔案讀取 Unicode 資料庫,就像您過去很長一段時間以來所做的那樣。因此,您不應直接讀取 Name.pl
,因為它的格式在 5.32 中已變更,而且未來可能會在沒有預告的情況下再次變更,甚至消失,您應該像這樣使用 "prop_invmap()"
my (%name, %cp, %cps, $n);
# All codepoints
foreach my $cat (qw( Name Name_Alias )) {
my ($codepoints, $names, $format, $default) = prop_invmap($cat);
# $format => "n", $default => ""
foreach my $i (0 .. @$codepoints - 2) {
my ($cp, $n) = ($codepoints->[$i], $names->[$i]);
# If $n is a ref, the same codepoint has multiple names
foreach my $name (ref $n ? @$n : $n) {
$name{$cp} //= $name;
$cp{$name} //= $cp;
}
}
}
# Named sequences
{ my %ns = namedseq();
foreach my $name (sort { $ns{$a} cmp $ns{$b} } keys %ns) {
$cp{$name} //= [ map { ord } split "" => $ns{$name} ];
}
}
use Unicode::UCD qw(prop_invmap prop_invlist);
use Unicode::UCD 'search_invlist';
my @invlist = prop_invlist($property_name);
print $code_point, ((search_invlist(\@invlist, $code_point) // -1) % 2)
? " isn't"
: " is",
" in $property_name\n";
my ($blocks_ranges_ref, $blocks_map_ref) = prop_invmap("Block");
my $index = search_invlist($blocks_ranges_ref, $code_point);
print "$code_point is in block ", $blocks_map_ref->[$index], "\n";
search_invlist
用於搜尋由 prop_invlist
或 prop_invmap
傳回的反轉清單,以找出特定的 "碼位引數"。如果反轉清單中找不到碼位,則會傳回 undef
(這只會發生在碼位不是合法的 "碼位引數",或小於清單的第一個元素時)。在第一個實例中會提出警告。
否則,它會傳回清單中包含碼位的範圍索引;也就是說,找出 i
,使得
list[i]<= code_point < list[i+1].
如 "prop_invlist()" 中所說明的,碼位是否在清單中取決於索引是偶數(在)或奇數(不在)。而且如 "prop_invmap()" 中所說明的,索引會與傳回的平行陣列一起使用,以找出對應關係。
這會傳回 Unicode 字元資料庫的版本,換句話說,就是資料庫實作的 Unicode 標準版本。版本是一個由點號('.'
)分隔的數字字串。
區塊與腳本的差別在於,腳本更接近於語言學中表示語言所需的碼位集合的概念,而區塊則是 Unicode 碼位編號和分隔成連續碼位區塊的產物(到目前為止,區塊的大小都是 16 的倍數,例如 128 或 256)。
例如,拉丁文字分佈在幾個區塊中,例如 基本拉丁文
、拉丁文 1 補充
、拉丁文延伸-A
和 拉丁文延伸-B
。另一方面,拉丁文字並不包含 基本拉丁文
區塊(也稱為 ASCII)的所有字元:它僅包含字母,不包含數字或標點符號。
有關區塊,請參閱 http://www.unicode.org/Public/UNIDATA/Blocks.txt
有關文字,請參閱 UTR #24:http://www.unicode.org/reports/tr24/
文字與正規表示式結構 \p{...}
相符(例如 \p{Tibetan}
與藏文字的字元相符),而 \p{Blk=...}
則用於區塊(例如 \p{Blk=Tibetan}
與藏文字區塊中的 256 個碼點相符)。
Unicode 以兩種不同的樣式發布區塊名稱,不過這兩種樣式在 Unicode 的寬鬆對應規則下是等效的。
原始樣式在區塊名稱中使用空白和連字號(No_Block
除外),如下所示
Miscellaneous Mathematical Symbols-B
較新的樣式將這些空白和連字號替換為底線,如下所示
Miscellaneous_Mathematical_Symbols_B
這種較新的樣式與其他 Unicode 屬性的值一致。為了保持向後相容性,Unicode::UCD 中所有傳回區塊名稱的函數(除非另有說明)都會傳回舊式名稱。 "prop_value_aliases()" 會傳回新式名稱,可用於將舊式名稱轉換為新式名稱
my $new_style = prop_values_aliases("block", $old_style);
Perl 也有單一形式的延伸,用於指稱區塊,In_Cyrillic
,表示 Block=Cyrillic
。這些延伸一直都是以新式樣式撰寫的。
若要將新式名稱轉換為舊式名稱,請遵循下列步驟
$old_style = charblock((prop_invlist("block=$new_style"))[0]);
(使用 prop_invlist
找出區塊中的碼點範圍,取得範圍的較低端(第 0 個元素),然後使用 charblock
查詢區塊的舊式名稱)。
請注意,從 Unicode 6.1 開始,許多區塊名稱都有較短的同義詞。這些同義詞總是使用新式樣式。
此模組中的函式在較早的 Unicode 版本中使用時,其運作方式與預期的一樣。但顯然地,它們使用該 Unicode 版本中可用的資料。例如,如果 Unicode 版本早於腳本屬性的定義(Unicode 3.1),則任何處理腳本的函式都會為回傳值的腳本部分回傳 undef
。
Jarkko Hietaniemi。目前由 perl5 維護人員維護。