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()" 函数。
哈希中的键及其值的含义是
输入本机 "代码点参数" 以十六进制表示,如果需要,则添加前导零以使其至少包含四个十六进制数字
code 的名称,全部大写。某些控制类型代码点没有名称。此字段对于代理
和专用使用
代码点将为空,对于其他没有名称的代码点,它将包含用尖括号括起来的一个描述,如 <control>
。
code 的通用类别的简称。这将与 "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()" 函数获取双向类型名称的所有同义词。
如果代码没有分解,则为空;或者是一个或多个代码(用空格分隔),按顺序表示代码的分解。每个至少有四个十六进制数字。这些代码可能前面有一个用尖括号括起来的一个单词,然后是一个空格,例如 <compat>
,给出分解的类型
此分解可能是中间分解,其组件也可以分解。使用 Unicode::Normalize 一步获取最终分解。
如果代码表示十进制数字,则这是它的整数数值
如果代码表示其他一些类似数字的数字,则这是它的整数数值
如果代码表示整数或有理数,则这是它的数值。有理数表示为类似 1/4
的字符串。
Y
或 N
,指定代码在双向文本中是否镜像
如果此代码点存在且与当前名称不同,则代码在 Unicode 1.0 标准中的名称
从 Unicode 6.0 开始,这始终为空。
如果非空,则是代码的大写映射,表示为至少四个十六进制数字。这表示完整的大写映射是一个字符,并且与简单的(仅单字符)映射相同。当此字段为空时,表示简单的大写映射是代码本身;您需要其他一些方法(如 "charprop()" 或 "casespec()" 来获取完整映射。
如果非空,则是代码的小写映射,表示为至少四个十六进制数字。这表示完整的小写映射是一个字符,并且与简单的(仅单字符)映射相同。当此字段为空时,表示简单的小写映射是代码本身;您需要其他一些方法(如 "charprop()" 或 "casespec()" 来获取完整映射。
如果非空,则为代码的标题大小写映射,表示为至少四个十六进制数字。这表示完整的标题大小写映射是一个字符,并且与简单的(仅单字符)映射相同。当此字段为空时,表示简单的标题大小写映射是代码本身;您需要其他方法(如 "charprop()" 或 "casespec()")来获取完整的映射。
代码所属的块(用于 \p{Blk=...}
)。"prop_value_aliases()" 函数可用于获取块名称的所有同义词。
请参阅 "块与脚本"。
代码所属的脚本。"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
哈希元素中获取此值。
应特别注意几个属性的返回值
返回的值是新样式(请参见 "旧样式与新样式块名称")。
与 "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
为所有仅限内部使用的 Perl 扩展返回 undef
。
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()
返回代码点所属的脚本,例如 拉丁文
、希腊文
、汉语
。如果代码点未分配或使用的 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=...}
构造之外,你还可以使用 charinrange()
测试代码点是否在 “charblock()” 和 “charscript()” 返回的范围内,或在 “charblocks()” 和 “charscripts()” 返回的哈希的值中。
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
)作为键,长名称(例如 Left-to-Right
、Right-to-Left
)作为值。如果您需要从长名称转到短名称,则散列可逆。bidi 类型是从 "charinfo()" 返回的,在 bidi
键下。有关各种 bidi 类的确切含义,建议阅读 Unicode TR9: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()
返回 full
映射(如下所述),速度比这更快,并且适用于整个字符串。)
如果没有输入代码点的折叠,则返回 undef
。
如果该代码点存在大小写折叠,则返回对具有以下字段的哈希的引用
输入本机 "代码点参数" 以十六进制表示,如果需要,则添加前导零以使其至少包含四个十六进制数字
一个或多个代码(用空格分隔),按顺序给出code大小写折叠的代码点。每个代码至少有四个十六进制数字。
为空,或恰好是一个至少有四个十六进制数字的代码,当调用程序无法处理折叠为多个代码点序列时,可以用作替代大小写折叠。如果full仅为一个代码点,则simple等于full。如果未为code定义单个代码点折叠,则simple为空字符串。否则,它是一个较差的,但仍然优于full的替代折叠。
如果simple不为空,则与simple相同,否则与full相同。可以将其视为code最简单的折叠。它主要出于向后兼容性而定义。
如果最佳折叠是单个代码点(simple等于full等于mapping),则为C
(表示common
)。如果存在不同的折叠,simple和full(mapping等于simple),则为S
。如果仅存在一个full折叠(mapping等于full;simple为空),则为F
。请注意,这描述了mapping的内容。它主要出于向后兼容性而定义。
对于 3.1 至 3.1.1(含)之间的 Unicode 版本,status还可以是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 字母大小写映射永远不会比单个代码点长)。
如果没有 "代码点参数" 的字母大小写映射,或者如果所有三个可能的映射(lower、title 和 upper)都产生单个代码点并且与语言环境无关且无条件,则返回 undef
(这意味着代码点的字母大小写映射(如果有)是由 "charinfo()" 返回的)。
否则,将返回一个引用,引用一个给出映射的哈希(或引用一个此类哈希的哈希,如下所述),其中包含以下键及其含义
底层哈希中的键及其值的含义为
输入本机 "代码点参数" 以十六进制表示,如果需要,则添加前导零以使其至少包含四个十六进制数字
一个或多个代码(用空格分隔),按顺序提供code小写形式的代码点。每个代码至少有四个十六进制数字。
一个或多个代码(用空格分隔),按顺序提供code标题形式的代码点。每个代码至少有四个十六进制数字。
一个或多个代码(用空格分隔),按顺序提供code大写形式的代码点。每个代码至少有四个十六进制数字。
映射有效的条件。如果为undef
,则映射始终有效。定义时,此字段为条件列表,其中所有条件都必须为真,映射才有效。该列表由一个或多个语言环境(见下文)和/或上下文(在下一段中解释)组成,用空格分隔。(除了用于分隔元素外,应忽略空格。)条件列表中的大小写不重要。以“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 的值为 "Basic Latin"。第二行中 @blocks_ranges 列中的条目 "0x0080" 表示第一行中的值 "Basic Latin" 扩展到从 0 开始到但不包括 0x0080 的范围内的所有代码点,即到 127。换句话说,0 到 127 的代码点都在 "Basic Latin" 块中。类似地,从 0x0080 到(但不包括)0x0100 范围内的所有代码点都在名为 "Latin-1 Supplement" 的块中,依此类推。(请注意,返回的是旧式块名称;请参阅 "旧式与新式块名称")。
最后一行(索引 [242])表示高于合法 Unicode 最大代码点的所有代码点的值均为 "No_Block",这是 Unicode 用于不存在的块的术语。
这些数组完全指定了所有可能的代码点的映射。此函数返回的反转映射中的最后一个元素将始终属于一个范围,该范围由所有非法的 Unicode 代码点组成,但可以在平台上表示。(也就是说,它从代码点 0x110000 开始,这是超过合法 Unicode 最大值的第一个代码点,并一直延伸到无穷大。)该范围的值将与任何典型的未分配代码点对于指定属性所具有的值相同。(某些未分配代码点并非“典型”;例如,非字符代码点或那些在从右到左书写的块中的代码点。高于 Unicode 的范围的值并不基于这些非典型代码点。)有人可能会认为,与其将这些代码点视为未分配的 Unicode 代码点,不如将此范围的值设置为 undef
。如果您愿意,可以相应地更改返回的数组。
几乎所有属性的映射都是应该按原样解释的简单标量。这些值是 Unicode 提供的数据文件中给出的值,这些值在大小写和给出的属性值同义词方面可能不一致。可以通过使用 "prop_value_aliases()" 函数对结果进行规范化。
简单的标量映射有一些例外。某些属性在其映射列表中有一些元素本身是标量列表;并且返回了一些不应按原样解释的特殊字符串。在上面示例中放入 $format
中的元素 [2](返回的四个元素列表)告诉您映射是否具有任何这些特殊元素,如下所示
s
表示映射数组的所有元素都是简单的标量,没有特殊元素。几乎所有属性都像这样,例如上面的 block
示例。
sl
表示映射数组元素中的一些具有 "s"
给出的形式,而其余的是标量列表。例如,以下是使用“脚本扩展”属性调用 prop_invmap
() 的输出的一部分
@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
表示分解映射属性。此属性类似于 "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";
有了这个,如果其输入代码点映射到 $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 维护者维护。