这是命令 perlunicode,可以使用我们的多个免费在线工作站之一在 OnWorks 免费托管服务提供商中运行,例如 Ubuntu Online、Fedora Online、Windows 在线模拟器或 MAC OS 在线模拟器
程序:
您的姓名
perlunicode - Perl 中的 Unicode 支持
商品描述
如果您还没有,在阅读本文档之前,您应该熟悉两者
perlunitut 和 perluniintro。
Unicode 旨在 UNI-fy 英语-守则- 将世界上所有的字符集合并为一个
标准。 对于许多在 Unicode 出现时存在的各种编码标准
首先创建,从每个转换为 Unicode 本质上意味着向每个添加一个常量
原始标准中的代码点,转换回来意味着只需减去相同的
持续的。 对于 ASCII 和 ISO-8859-1,常量为 0。对于 ISO-8859-5,(西里尔文)
常数为 864; 对于希伯来语 (ISO-8859-8),它是 1488; 泰语(ISO-8859-11),3424; 所以
向前。 这使得转换变得容易,并促进了 Unicode 的采用。
它奏效了; 如今,这些遗留标准很少使用。 大多数人都使用
Unicode。
Unicode 是一个综合性标准。 它指定了 Perl 范围之外的许多东西,
例如如何显示字符序列。 对所有方面的全面讨论
Unicode,见http://www.unicode.org>.
重要 注意事项
即使您在第一次阅读时可能无法理解本节中的某些内容,我们
认为在进一步深入研究之前突出一些问题很重要,所以
开始:
Unicode 支持是一项广泛的要求。 虽然 Perl 没有实现 Unicode
标准或随附的技术报告从头到尾,Perl 确实支持许多
Unicode 功能。
此外,Unicode 的使用可能会带来不明显的安全问题。 读取 Unicode
安全注意事项http://www.unicode.org/reports/tr36>.
如果您“使用功能‘unicode_strings’”,则最安全
为了保持向后兼容性,Perl 没有开启完全内部
Unicode 支持,除非指定了编译指示“使用功能 'unicode_strings'”。 (这个
如果您“使用 5.012”或更高版本,则会自动选择。)如果不这样做可能会
引发意想不到的惊喜。 请参阅下面的“Unicode 错误”。
此编译指示不影响 I/O。 它也不会改变内部表示
字符串,只有它们的解释。 Unicode 还有几个地方
不完全支持,例如在文件名中。
输入和输出层
使用 ":encoding(...)" 层使用
指定的编码。 (见打开。)
您应该将非 ASCII、非 UTF-8 Perl 脚本转换为 UTF-8。
见编码。
在脚本中启用 UTF-8 仍需要“使用 utf8”
如果您的 Perl 脚本本身以 UTF-8 编码,则“use utf8”编译指示必须是
明确包含以启用识别(在字符串或正则表达式中
文字,或在标识符名称中)。 本篇 is 这些因素包括原料奶的可用性以及达到必要粉末质量水平所需的工艺。 仅由 次 ,尤其是 an 明确的 “用 utf8"
is 需要。 (见utf8)。
自动检测“BOM”标记的脚本和 UTF-16 脚本
但是,如果 Perl 脚本以 Unicode“BOM”(UTF-16LE、UTF16-BE 或
UTF-8),或者如果脚本看起来像非“BOM”标记的 UTF-16 字节序,Perl
将正确读取脚本作为适当的 Unicode 编码。 (“BOM”-less
UTF-8 无法有效识别或区别于 ISO 8859-1 或其他
八位编码。)
字节 和 字符 语义
在 Unicode 之前,大多数编码使用 8 位(单个字节)来对每个字符进行编码。 因此
一个字符就是一个字节,一个字节就是一个字符,只能有 256 个或更少
可能的字符。 本节标题中的“字节语义”指的是这个
行为。 没有必要区分“字节”和“字符”。
然后是 Unicode,它有超过一百万个字符的空间(Perl 允许
更)。 这意味着一个字符可能需要多个字节来表示
它,因此这两个术语不再等效。 这些字符有什么关系
整个实体,而不是通常包含它们的字节。 这就是这个词
本节标题中的“字符语义”是指。
Perl 必须在内部进行更改以将“字节”与“字符”分离。 重要的是
你也改变了你的想法,如果你还没有的话,那么“字节”和“字符”就没有了
在你的脑海中,更长的意思是同样的事情。
Perl 字符串的基本构建块一直是“字符”。 变化
基本上归结为实现不再认为角色总是
只是一个字节。
有各种注意事项:
· 字符串处理函数,在大多数情况下,继续在
人物。 “length()”,例如,返回字符串中的字符数,
就像以前一样。 但该数字不再一定与
字符串中的字节数(字节数可能多于字符数)。 另一个这样的
函数包括“chop()”、“chomp()”、“substr()”、“pos()”、“index()”、“rindex()”、
“sort()”、“sprintf()”和“write()”。
例外情况是:
· 面向位的“vec”
· 面向字节的“打包”/“解包”“C”格式
但是,“W”说明符确实对整个字符进行操作,“U”也是如此
说明符。
· 一些与平台操作系统交互的操作符
处理文件名的运算符就是例子。
· 从“使用字节”编译指示的范围内调用函数时
很可能,无论如何,您应该仅将其用于调试。
· 字符串——包括散列键——和正则表达式模式可能包含字符
序数值大于 255 的。
如果使用 Unicode 编辑器编辑程序,可能会出现 Unicode 字符
直接在 UTF-8 编码或 UTF-16 的文字字符串中。 (前者
需要“BOM”或“使用 utf8”,后者需要“BOM”。)
perluniintro 中的“创建 Unicode”提供了其他方法来放置非 ASCII 字符
你的字符串。
· "chr()" 和 "ord()" 函数对整个字符起作用。
· 正则表达式匹配整个字符。 例如, ”。” 匹配一个整体
字符而不是单个字节。
· "tr///" 操作符翻译整个字符。 (注意“tr//CU”
功能已被删除。 有关与此类似的功能,请参阅“pack('U0',
...)”和“pack('C0', ...)”)。
· "scalar reverse()" 按字符而不是按字节反转。
· 位串运算符,“& | ^ ~”和(从 v5.22 开始)“&. |. ^. ~.” 可以操作
在不适合一个字节的字符上。 然而,目前的行为很可能
改变。 您不应在以 UTF-8 编码的字符串上使用这些运算符。 如果
您不确定字符串的编码,请在使用其中任何一个之前将其降级
运营商; 您可以使用“utf8::utf8_downgrade()”。
底线是 Perl 一直在实践“字符语义”,但是随着
Unicode 的出现,现在不同于“字节语义”。
ASCII码 规则 而不是 统一 规则
在 Unicode 之前,当一个字符是一个字节时,Perl 只知道 128
由 ASCII 定义的字符,代码点 0 到 127(“使用区域设置”下除外)。
这使得代码点 128 到 255 未分配,并且可用于任何用途
程序可能想要。 它们唯一的语义是它们的序数,并且它们
不是任何非负字符类的成员。 没有一个被认为是匹配的
例如“\w”,但都匹配“\W”。
当然,Unicode 为这些代码点中的每一个分配了特定的含义(以及
255 以上)。 为了保持向后兼容性,Perl 仅使用 Unicode 含义
当有迹象表明 Unicode 符合预期时; 否则非 ASCII
代码点仍然被视为未分配。
下面是 Perl 知道字符串应该被视为 Unicode 的方式:
· 在“使用utf8”范围内
如果整个程序是 Unicode(用 8 位表示 U代码 T转型
Format),那么其中的所有字符串都必须是 Unicode。
· 在“使用特性'unicode_strings'”的范围内
创建此 pragma 是为了让您可以明确地告诉 Perl 执行的操作
在其范围内使用 Unicode 规则。 更多操作受到更新的影响
珍珠。 请参阅“Unicode 错误”。
· 在“使用5.012”或更高的范围内
这隐含地打开“使用功能'unicode_strings'”。
· 在“使用语言环境'not_characters'”范围内,或“使用语言环境”和当前
语言环境是 UTF-8 语言环境。
前者被定义为暗示 Unicode 处理; 后者表示一个Unicode
语言环境,因此对其中的所有字符串进行 Unicode 解释。
· 当字符串包含仅 Unicode 代码点时
Perl 从来没有接受超过 255 的代码点,除非它们是 Unicode,所以它们的使用
意味着整个字符串的 Unicode。
· 当字符串包含一个 Unicode 命名的代码点“\N{...}”
"\N{...}" 构造显式地引用一个 Unicode 代码点,即使它是一个
这也是ASCII。 因此包含它的字符串必须是 Unicode。
· 当字符串来自标记为 Unicode 的外部源时
“-C”命令行选项可以指定程序的某些输入是
Unicode,并且它的值可以通过你的 Perl 代码读取,参见“${^UNICODE}”
珀尔瓦尔。
· 当字符串已经升级到UTF-8
函数“utf8::utf8_upgrade()”可以显式地用于永久(除非
随后的“utf8::utf8_downgrade()”被调用)导致一个字符串被视为
Unicode。
· 正则表达式模式有额外的方法
使用“/u”或“/a”修饰符编译的模式被视为Unicode
(尽管“/a”有一些限制)。 在“/d”和“/l”修饰符下,
还有其他几种 Unicode 指示; 参见“字符集修饰符”
佩尔。
请注意,以上所有内容都在“使用字节”的范围内被覆盖; 但你应该
此编译指示仅用于调试。
另请注意,与平台操作系统的某些交互从不使用 Unicode
规则。
当 Unicode 规则生效时:
· 大小写转换操作符使用Unicode 大小写转换表。
请注意,内插字符串中的“uc()”或“\U”转换为大写,而
内插字符串中的“ucfirst”或“\u”在以下语言中转换为titlecase
进行区分(相当于在没有
区别)。
有一个 CPAN 模块,“Unicode::Casing”,它允许你定义你自己的
“lc()”、“lcfirst()”、“uc()”、“ucfirst()”和“fc”(或它们的
双引号字符串内联版本,例如“\U”)。 (在 Perl 5.16 之前,这个
Perl 核心提供了部分功能,但受到许多
无法克服的缺点,因此编写了 CPAN 模块。)
· 正则表达式中的字符类根据字符属性进行匹配
在 Unicode 属性数据库中指定。
例如,“\w”可用于匹配日文表意文字; 和 "[[:digit:]]" 一个
孟加拉数字。
· 可以使用命名的 Unicode 属性、脚本和块范围(如括号
字符类)通过使用“\p{}”“匹配属性”构造和“\P{}”
否定,“与属性不匹配”。
有关更多详细信息,请参阅“Unicode 字符属性”。
您可以定义自己的字符属性并在正则表达式中使用它们
使用“\p{}”或“\P{}”构造。 有关更多信息,请参阅“用户定义的字符属性”
细节。
扩展 字形 集群 (逻辑 字符)
考虑一个字符,比如说“H”。 它周围可能会出现各种标记,例如
锐重音,抑扬抑扬格,或各种钩子、圆圈、箭头, 等等,上面,下面,到
一侧或另一侧, 等。. 世界语言之间有很多可能性。
组合的数量是天文数字,如果每个组合都有一个字符
结合起来,它很快就会耗尽 Unicode 的超过一百万个可能的字符。 所以
Unicode 采取了不同的方法:有一个字符作为基本的“H”,一个字符
对于每个可能的标记,这些可以不同地组合以获得最终的逻辑
特点。 所以一个逻辑字符——看起来是一个单一的字符——可以是一个
多个单独字符的序列。 Unicode 标准将这些称为
“扩展的字素簇”(这是不再经常使用的改进版本
"字素簇"); Perl 提供了“\X”正则表达式结构来匹配这样的
整个序列。
但 Unicode 的意图是统一现有的字符集标准和实践,并且
一些预先存在的标准具有单个字符,与某些标准具有相同的含义
这些组合,例如 ISO-8859-1,其中有不少。 例如,“拉丁
当 Unicode 出现时,带有 ACUTE 的大写字母 E”已经在这个标准中了。
因此,Unicode 将它作为单个字符添加到其曲目中。 但是这个性格
被 Unicode 视为等价于由字符组成的序列
“拉丁文大写字母 E”后跟字符“COMBINING ACUTE ACCENT”。
“LATIN CAPITAL LETTER E WITH ACUTE”被称为“预编”字符,其
与“E”和“COMBINING ACCENT”序列的等价称为规范
等价。 据说所有预先组合的字符都有一个分解(到
等效序列),分解类型也称为规范。 一个字符串可能
尽可能多地由预先组合的字符组成,或者它可能由
完全分解的字符。 Unicode 将这些分别称为“规范化形式
组合”(NFC)和“规范化形式分解”。“Unicode::Normalize”模块
包含在两者之间转换的函数。 一个字符串也可以同时包含
字符和分解字符; 此模块可用于使其全部成为一个或
等。
您可能会看到任何这些等效形式的字符串。 目前有
Perl 5 中没有任何内容可以忽略差异。 所以你必须专门处理它。
通常的建议是在进一步处理之前将您的输入转换为“NFD”。
有关更多详细信息,请参阅http://unicode.org/reports/tr15/>.
统一 字符 查看房源
(Perl 唯一一次将单个代码点序列视为单个代码点
逻辑字符在“\X”结构中,上面已经提到过。 所以
本讨论中的“字符”表示单个 Unicode 代码点。)
几乎所有 Unicode 字符属性都可以通过正则表达式访问
使用“\p{}”“匹配属性”构造和“\P{}”“不匹配属性”
它的否定。
例如,"\p{Uppercase}" 匹配任何带有 Unicode "Uppercase" 的单个字符
属性,而 "\p{L}" 匹配任何 "General_Category" 为 "L"(字母)的字符
属性(请参阅下面的“General_Category”)。 单字母不需要括号
属性名称,所以“\p{L}”等价于“\pL”。
更正式地说,"\p{Uppercase}" 匹配任何单个字符的 Unicode "Uppercase"
属性值为“True”,“\P{Uppercase}”匹配任何具有“Uppercase”的字符
属性值为“False”,它们可以写成“\p{Uppercase=True}”和
"\p{Uppercase=False}",分别。
当属性不是二进制时需要这种形式; 也就是说,如果他们可以承担更多
值不仅仅是“真”和“假”。 例如,“Bidi_Class”属性(参见
下面的“双向字符类型”),可以采用几个不同的值,例如
“左”、“右”、“空白”等。 为了匹配这些,需要同时指定
属性名称(“Bidi_Class”),以及匹配的值(“Left”、“Right”、 等等).
与上面的示例一样,这是通过将两个组件由相等的
符号(或可互换,冒号),如“\p{Bidi_Class: Left}”。
所有 Unicode 定义的字符属性都可以用这些复合形式编写
"\p{属性=值}” 或“\p{适当的价值}”, 但 Perl 提供了一些额外的属性
仅以单一形式编写的,以及所有二进制文件的单一形式快捷方式
属性和下面描述的某些其他属性,您可以在其中省略属性名称和
等号或冒号分隔符。
大多数 Unicode 字符属性至少有两个同义词(或别名,如果您愿意):
短的更容易打字,长的更具描述性,因此
更容易理解。 因此上面的“L”和“Letter”属性是等价的,并且可以
可以互换使用。 同样,“Upper”是“Uppercase”的同义词,我们可以
已经将 "\p{Uppercase}" 等价地写为 "\p{Upper}"。 此外,通常还有
属性值的各种同义词。 对于二元属性,“True”有 3
同义词:“T”、“是”和“Y”; 和“假”相应地有“F”、“否”和“N”。 但被
小心。 一个属性的值的缩写形式可能与相同的事物不同
另一个的简称。 因此,对于“General_Category”属性,“L”表示“字母”,
但对于“Bidi_Class”属性,“L”表示“左”。 完整的属性列表和
同义词在 perluniprops 中。
属性名称和值的大小写差异无关紧要; 因此“\p{上}”
与“\p{upper}”甚至“\p{UpPeR}”的意思相同。 同样,您可以添加或
在单词中间的任何地方减去下划线,这样它们也是等价的
到“\p{U_p_p_e_r}”。 与非单词字符相邻的空白是无关紧要的,例如
作为大括号和等号或冒号分隔符,所以 "\p{ Upper }" 和 "\p{ Upper_case
:Y }" 也等价于这些。实际上,空格甚至连字符通常都可以
在任何地方添加或删除。 所以即使是 "\p{ Up-per case = Yes}" 也是等价的。 这些所有
被 Unicode 称为“松散匹配”。 使用更严格匹配的少数地方是
在数字的中间,以及以字母开头或结尾的 Perl 扩展属性中
下划线。 更严格的匹配关心空格(除了与非单词相邻的
字符)、连字符和非内部下划线。
您还可以通过在“\p{}”和“\P{}”之间引入插入符号(“^”)来使用否定
第一个大括号和属性名称:“\p{^Tamil}”等于“\P{Tamil}”。
几乎所有属性都不受不区分大小写匹配的影响。 也就是说,添加一个“/i”
正则表达式修饰符不会改变它们匹配的内容。 有两套是
做作的。 第一组是“Uppercase_Letter”、“Lowercase_Letter”和
“Titlecase_Letter”,都匹配“/i”匹配下的“Cased_Letter”。 第二个
set 是“Uppercase”、“Lowercase”和“Titlecase”,它们都匹配“/i”下的“Cased”
匹配。 该集合还包括其子集“PosixUpper”和“PosixLower”
在“/i”下匹配“PosixAlpha”。 (这些集合之间的区别在于,有些东西,
例如罗马数字,有大写和小写,所以它们是“Cased”的,但不是
被视为字母,因此它们不是“Cased_Letter”。)
有关匹配 Unicode 时的特殊注意事项,请参阅“超越 Unicode 代码点”
针对非 Unicode 代码点的属性。
一般类别
每个 Unicode 字符都被分配了一个通用类别,这是“最常见的
字符的分类”(来自http://www.unicode.org/reports/tr44>)。
编写这些的复合方式就像“\p{General_Category=Number}”(简称:
“\p{gc:n}”)。 但是 Perl 提供了捷径,其中一切都通过平等或
省略了冒号分隔符。 所以你可以只写“\pN”。
以下是“General Category”属性可以具有的值的短形式和长形式:
短长
L 字母
LC, L& Cased_Letter(即:[\p{Ll}\p{Lu}\p{Lt}])
卢大写_字母
Ll 小写_字母
Lt Titlecase_字母
Lm 修饰符_字母
罗其他_信件
马克
Mn 无间距_Mark
Mc间距_标记
我封闭_标记
N号
Nd Decimal_Number(也是数字)
Nl 字母_数字
没有其他_号码
P 标点符号(也称为标点符号)
电脑连接器_标点符号
Pd Dash_标点符号
Ps 打开_标点符号
Pe Close_标点符号
Pi 首字母_标点符号
(根据使用情况,可能表现得像 Ps 或 Pe)
Pf Final_Punctuation 标点符号
(根据使用情况,可能表现得像 Ps 或 Pe)
宝其他_标点符号
S 符号
Sm 数学_符号
Sc 货币_符号
Sk修饰符_Symbol
所以 Other_Symbol
Z 分隔符
Zs 空格分隔符
Zl线_分隔符
Zp 段落_分隔符
C 其他
抄送控制(也控制)
CF格式
Cs 代孕
私人使用
Cn 未分配
单字母属性匹配任何两个字母子属性中的所有字符
以同一个字母开头。 “LC”和“L&”是特殊的:都是集合的别名
由与“Ll”、“Lu”和“Lt”匹配的所有内容组成。
双向 字符 类型
因为脚本的方向不同(希伯来语和阿拉伯语的书写正确
左边,例如)Unicode 提供了一个“Bidi_Class”属性。 这其中的一些值
属性可以有:
价值意义
L 从左到右
LRE 从左到右嵌入
LRO 从左到右覆盖
R 从右到左
AL 阿拉伯字母
RLE 从右到左嵌入
RLO 从右到左覆盖
PDF 流行方向格式
CN 欧洲号码
ES欧洲分离器
ET欧洲终结者
一个阿拉伯数字
CS 通用分隔符
NSM 非间距标记
BN边界中性
B 段落分隔符
S段分隔符
WS 空白
ON 其他中性
此属性始终以复合形式编写。 例如,“\p{Bidi_Class:R}”
匹配通常从右到左书写的字符。 与“General_Category”不同
属性,此属性可以在未来的 Unicode 版本中添加更多值。 那些
上面列出的包含许多 Unicode 版本的完整集合,但添加了其他版本
在 Unicode 6.3 中; 你总是可以在 perluniprops 中找到当前的内容。 和
<http://www.unicode.org/reports/tr9/> 描述如何使用它们。
脚本
世界上的语言是用许多不同的脚本编写的。 这句话(除非你是
阅读翻译)是用拉丁文写的,而俄文是用西里尔文写的,并且
希腊语是用希腊语写成的; 日语主要使用平假名或片假名。 有许多
更多。
Unicode "Script" 和 "Script_Extensions" 属性给出了给定字符的脚本
在。可以使用复合形式指定任一属性,如“\p{Script=Hebrew}”
(简称:“\p{sc=hebr}”),或“\p{Script_Extensions=Javanese}”(简称:“\p{scx=java}”)。 在
此外,Perl 为所有“脚本”属性名称提供快捷方式。 你可以省略
通过等号(或冒号)的所有内容,只需写“\p{Latin}”或
"\P{西里尔文}"。 (这不适用于“Script_Extensions”,它需要
写成复合形式。)
这两个属性之间的区别涉及在多个字符中使用的字符
脚本。 例如,数字“0”到“9”在世界许多地方使用。
这些被放置在一个名为“Common”的脚本中。 其他字符仅用于少数
脚本。 例如,“KATAKANA-HIRAGANA DOUBLE HYPHEN”在日语中都使用
脚本,片假名和平假名,但没有其他地方。 “脚本”属性将所有
在“通用”脚本中的多个脚本中使用的字符,而
“Script_Extensions”属性将那些仅在少数脚本中使用的内容放入每个脚本中
那些脚本; 同时仍然对许多脚本中使用的那些使用“通用”。 因此这两个
匹配:
"0" =~ /\p{sc=Common}/ # 匹配
"0" =~ /\p{scx=Common}/ # 匹配
并且只有第一个匹配:
"\N{片假名-平假名双连字符}" =~ /\p{sc=Common} # 匹配
"\N{片假名-平假名双连字符}" =~ /\p{scx=Common} # 不匹配
并且只有最后两个匹配:
"\N{片假名-平假名双连字符}" =~ /\p{sc=平假名} # 不匹配
"\N{片假名-平假名双连字符}" =~ /\p{sc=片假名} # 不匹配
"\N{片假名-平假名双连字符}" =~ /\p{scx=平假名} # 匹配
"\N{片假名-平假名双连字符}" =~ /\p{scx=片假名} # 匹配
“Script_Extensions”因此是一种改进的“脚本”,其中的字符较少
“通用”脚本,相应地在其他脚本中更多。 它是新的 Unicode
6.0 版本,其数据可能会在以后的版本中发生重大变化,因为事情
得到整理。 新代码可能应该使用“Script_Extensions”而不是简单的
“脚本”。
(实际上,除了“Common”之外,“Inherited”脚本中还包含用于
多个脚本。 这些是继承了脚本值的修饰符
控制字符。 其中一些在许多脚本中使用,因此进入“继承”
在“脚本”和“Script_Extensions”中。 其他的只用在几个脚本中,所以
在“脚本”中的“继承”中,但不在“Script_Extensions”中。)
值得强调的是,Unicode 中有几组不同的数字是
等价于 0-9 并且可以通过正则表达式中的 "\d" 匹配。 如果它们用于
只有一种语言,它们在该语言的“Script”和“Script_Extension”中。 如果
它们在多个脚本中使用,它们将在“sc=Common”中,但前提是它们是
如果它们在“scx=Common”中,则在许多脚本中使用。
脚本及其快捷方式的完整列表在 perluniprops 中。
使用 VHDL 语言编写 of 这些因素包括原料奶的可用性以及达到必要粉末质量水平所需的工艺。 “是” 字首
为了向后兼容(使用 Perl 5.6),所有属性都可写而不使用
到目前为止提到的复合形式可能在其名称前加上“Is”或“Is_”,所以
例如,“\P{Is_Lu}”等于“\P{Lu}”,而“\p{IsScript:Arabic}”等于
“\p{阿拉伯语}”。
吹氣梢
此外 脚本, Unicode 还定义了 块 的字符。 和...之间的不同
脚本和块是脚本的概念更接近自然语言,而
块的概念更多是基于 Unicode 组的人工分组
具有连续序数值的字符。 例如,“基本拉丁语”块是所有
序数在 0 到 127 之间的字符,包括 XNUMX 和 XNUMX; 换句话说,ASCII
人物。 “拉丁”脚本包含一些来自这个的字母以及其他几个
块,如“Latin-1 Supplement”、“Latin Extended-A”、 等等,但它不包含所有
这些块中的字符。 例如,它不包含数字 0-9,
因为这些数字在许多脚本中共享,因此在“通用”脚本中。
有关脚本与块的更多信息,请参阅 UAX#24“Unicode 脚本属性”:
<http://www.unicode.org/reports/tr24>
“Script”或“Script_Extensions”属性很可能是您想要使用的属性
处理自然语言时; “Block”属性有时可能有用
使用 Unicode 的具体细节。
块名称以复合形式匹配,例如 "\p{Block: Arrows}" 或
“\p{Blk=希伯来语}”。 与大多数其他属性不同,只有少数块名称具有 Unicode-
定义的简称。 但是 Perl 确实提供了一个(轻微的,不再推荐的)快捷方式:
例如,您可以说“\p{In_Arrows}”或“\p{In_Hebrew}”。
为了向后兼容,如果没有命名冲突,可以省略“In”前缀
使用脚本或任何其他属性,您甚至可以在这些属性中使用“Is”前缀
案件。 但是不要对新代码这样做,因为您的代码可能会在新版本中中断,并且
这已经发生了:在非常早期的 Unicode 版本中曾经有一段时间
"\p{Hebrew}" 将匹配 阻止 希伯来语; 现在没有了。
到目前为止,使用“In”前缀可以避免这种歧义。 但是新版本的 Unicode 还在继续
添加名称以“In”开头的新属性。 有可能是其中之一
它们总有一天会与您的用法发生冲突。 由于这只是一个 Perl 扩展,
Unicode 的名称将优先,您的代码将被破坏。 此外,Unicode 是
自由添加名称以“In”开头的脚本; 那会引起问题。
所以在指定块时使用复合形式更清晰,最好。 并且确定
这才是你真正想要做的。 在大多数情况下,脚本就是您想要的
代替。
完整的块列表及其快捷方式在 perluniprops 中。
其他 查看房源
除了这里描述的非常基本的属性之外,还有更多的属性。 完整清单
在 perluniprops 中。
Unicode 以复合形式定义其所有属性,因此所有单一形式的属性都是
Perl 扩展。 其中大部分只是 Unicode 的同义词,但有些是
真正的扩展名,包括几个复合形式的扩展名。 和相当多的
这些实际上是 Unicode 推荐的(在http://www.unicode.org/reports/tr18>)。
本节提供了所有扩展的一些详细信息,而不仅仅是复合的同义词-
形成 Unicode 属性(对于这些属性,您必须参考 Unicode
标准http://www.unicode.org/reports/tr44>.
"\p{全部}"
这匹配每个可能的代码点。 它相当于“qr/./s”。 不像所有的
其他非用户定义的 "\p{}" 属性匹配,如果这不会产生警告
is 属性与非 Unicode 代码点匹配(请参阅“Beyond Unicode code
点”下)。
"\p{专辑}"
这匹配任何 "\p{Alphabetic}" 或 "\p{Decimal_Number}" 字符。
"\p{任何}"
这匹配任何 1_114_112 Unicode 代码点。 它是的同义词
“\p{Unicode}”。
"\p{ASCII}"
这匹配 US-ASCII 字符集中的 128 个字符中的任何一个,这是一个
Unicode 的子集。
"\p{分配}"
这匹配任何分配的代码点; 也就是说,任何代码点的一般类别
不是“未分配”(或等效地,不是“Cn”)。
"\p{空白}"
这与“\h”和“\p{HorizSpace}”相同:改变间距的字符
水平地。
"\p{分解_类型: 非_规范}” (简称:“\p{Dt=NonCanon}”)
匹配具有非规范分解的字符。
上面的“扩展字素簇(逻辑字符)”一节讲到
规范分解。 然而,更多的角色有不同类型的
分解,“兼容”或“非规范”分解。 的序列
形式这些分解不被认为在规范上等同于前
组成的字符。 一个例子是“SUPERSCRIPT ONE”。 它有点像
常规数字 1,但不完全是; 它分解为数字 1 的过程称为
“兼容”分解,特别是“超级”分解。 有几种
这种兼容性分解(见http://www.unicode.org/reports/tr44>),
包括一个叫做“compat”的,这意味着一些杂项类型的分解
不适合 Unicode 选择的其他分解类别。
请注意,大多数 Unicode 字符没有分解,因此它们的分解
类型为“无”。
为方便起见,Perl 添加了“Non_Canonical”分解类型来表示
几种兼容性分解中的任何一种。
"\p{图}"
匹配任何图形字符。 理论上,这意味着一个字符
打印机会导致使用墨水。
"\p{地平线}"
这与“\h”和“\p{Blank}”相同:改变间距的字符
水平地。
"\p{In=*}"
这是“\p{Present_In=*}”的同义词
"\p{PerlSpace}"
这与 "\s" 相同,仅限于 ASCII,即 "[ \f\n\r\t]" 并从
Perl v5.18,一个垂直标签。
助记符:Perl 的(原始)空间
"\p{PerlWord}"
这与“\w”相同,仅限于ASCII,即“[A-Za-z0-9_]”
助记符:Perl 的(原始)词。
"\p{Posix...}"
其中有几个,它们是等价的,使用“\p{}”表示法,对于
Posix 类,并在 perlrecharclass 中的“POSIX 字符类”中进行了描述。
"\p{Present_In: *}" (短:“\p{In=*}”)
当您需要知道字符是什么 Unicode 版本时,将使用此属性。
上面的“*”代表一些两位数的Unicode版本号,比如1.1或者4.0; 或者
“*”也可以是“未分配”。 此属性将匹配其代码点
最终处置已在版本给出的 Unicode 版本中得到解决
数字; "\p{Present_In: Unassigned}" 将匹配那些含义为
尚未分配。
例如,“U+0041”“拉丁大写字母 A”出现在第一个 Unicode 中
可用版本,即 1.1,因此此属性对于所有有效的“*”版本都为真。
另一方面,“U+1EFF”直到版本 5.1 才被分配为“LATIN
带循环的小写字母 Y”,因此唯一匹配它的“*”是 5.1、5.2 和
后来。
Unicode 提供了从中派生的“年龄”属性。 年龄问题
是对它的严格解释(Perl 采用的)使它与精确的
释放代码点的含义被引入。因此“U+0041”将只匹配1.1;
而“U+1EFF”只有 5.1。 这通常不是您想要的。
Age 属性的一些非 Perl 实现可能会将其含义更改为
与 Perl 的“Present_In”属性相同; 请注意这一点。
这两个属性的另一个混淆是定义不是
代码点已经 分配,但代码点的含义已经
决心. 这是因为 66 个代码点将始终未分配,因此
他们的“年龄”是 Unicode 版本,在该版本中做出了使它们如此的决定。
例如,“U+FDD0”要永久不分配给一个字符,决定
要做到这一点是在 3.1 版中完成的,所以 "\p{Age=3.1}" 匹配这个字符,同样
做 "\p{Present_In: 3.1}" 及以上。
"\p{打印}"
这匹配任何图形或空白字符,控件除外。
"\p{SpacePerl}"
这与“\s”相同,包括超出 ASCII 的范围。
助记符:空格,由 Perl 修改。 (它不包括垂直选项卡,直到
v5.18,Posix 标准和 Unicode 都考虑了空白。)
"\p{标题}" 和 "\p{标题}"
在区分大小写的匹配下,它们都匹配与 "\p{General
Category=Titlecase_Letter}" ("\p{gc=lt}")。区别在于"/i"下无壳
匹配,这些匹配与“\p{Cased}”相同,而“\p{gc=lt}”匹配
"\p{Cased_Letter")。
"\p{Unicode}"
这匹配任何 1_114_112 Unicode 代码点。 “\p{任何}”。
"\p{VertSpace}"
这与“\v”相同:垂直改变间距的字符。
"\p{字}"
这与“\w”相同,包括超过 100_000 个 ASCII 字符。
"\p{XPosix...}"
其中有几个,它们是扩展到完整的标准 Posix 类
Unicode 范围。 它们在 perlrecharclass 的“POSIX 字符类”中进行了描述。
用户自定义 字符 查看房源
您可以通过定义名称的子例程来定义自己的二进制字符属性
以“In”或“Is”开头。 (perlre 中的实验特性“(?[ ])”提供了一个
另一种允许更复杂的定义。)子程序可以在任何
包裹。 用户定义的属性可以用在正则表达式 "\p{}" 和
"\P{}" 构造; 如果您使用的是包中的用户定义属性,而不是
你所在的一个,你必须在 "\p{}" 或 "\P{}" 结构中指定它的包。
# 假设属性 Is_Foreign 定义在 Lang::
包主; # 需要属性包名
如果 ($txt =~ /\p{Lang::IsForeign}+/) { ... }
包郎; # 不需要属性包名
如果 ($txt =~ /\p{IsForeign}+/) { ... }
请注意,效果是编译时的,并且一旦定义便不可变。 但是,子程序
传递单个参数,如果区分大小写匹配有效,则为 0
如果无大小写匹配有效,则为零。 子程序可能返回不同的值
取决于标志的值,并且一组值将永远有效
所有区分大小写的匹配项,另一个设置为所有不区分大小写的匹配项。
请注意,如果正则表达式被污染,那么 Perl 将死亡而不是调用
subroutine 当子例程的名称由受污染数据确定时。
子程序必须返回一个特殊格式的字符串,带有一个或多个换行符-
分隔线。 每行必须是以下之一:
· 表示要包含的代码点的单个十六进制数。
· 由水平空白(空格或表格)分隔的两个十六进制数
字符)表示要包含的代码点范围。
· 要包含的东西,以“+”为前缀:一个内置的字符属性(以
"utf8::") 或一个完全限定的(包括包名)用户定义的字符
属性,表示该属性中的所有字符; 两个十六进制代码
一个范围的点数; 或单个十六进制代码点。
· 要排除的东西,前缀为“-”:现有字符属性(前缀为
"utf8::") 或一个完全限定的(包括包名)用户定义的字符
属性,表示该属性中的所有字符; 两个十六进制代码
一个范围的点数; 或单个十六进制代码点。
· 否定的东西,前缀“!”:现有的字符属性(前缀为
"utf8::") 或一个完全限定的(包括包名)用户定义的字符
属性,表示该属性中的所有字符; 两个十六进制代码
一个范围的点数; 或单个十六进制代码点。
· 相交的东西,前缀为“&”:一个现有的字符属性(前缀为
由“utf8::”)或一个完全限定的(包括包名)用户定义的字符
属性,对于除属性中的字符外的所有字符; 二
范围的十六进制代码点; 或单个十六进制代码点。
例如,要定义一个涵盖日语音节(平假名和
片假名),你可以定义
子假名{
返回<
3040\t309F
30A0\t30FF
END
}
想象一下 here-doc 结束标记位于行的开头。 现在你可以使用
"\p{InKana}" 和 "\P{InKana}"。
您也可以使用现有的块属性名称:
子假名{
返回<<'END';
+utf8::在平假名
+utf8::In片假名
END
}
假设您只想匹配分配的字符,而不是原始块范围:
换句话说,您要删除未分配的字符:
子假名{
返回<<'END';
+utf8::在平假名
+utf8::In片假名
-utf8::IsCn
END
}
否定对于定义(惊喜!)否定类很有用。
子 InNotKana {
返回<<'END';
!utf8::在平假名
-utf8::In片假名
+utf8::IsCn
END
}
这将匹配所有非 Unicode 代码点,因为它们中的每一个都不是假名。 你
如果需要,可以使用交集来排除这些,如此修改后的示例所示:
子 InNotKana {
返回<<'END';
!utf8::在平假名
-utf8::In片假名
+utf8::IsCn
&utf8::任何
END
}
&utf8::Any 必须是定义的最后一行。
交集通常用于获取两个(或多个)匹配的公共字符
类。 重要的是要记住不要在第一组中使用“&”; 那将是
与空无相交,导致空集。
与非用户定义的 "\p{}" 属性匹配不同,如果这些属性匹配,则不会生成任何警告
属性与非 Unicode 代码点匹配(请参阅“超越 Unicode 代码点”
下文)。
用户自定义 案例 映射 (用于 严重 黑客 只有)
本篇 特集 具有 很 去除 as of Perl的 5.16. CPAN 模块“Unicode::Casing”提供
更好的功能而没有此功能的缺点。 如果您使用的是 Perl
在 5.16 之前,此功能在此 pod 的 5.14 版本中得到了最完整的记录:
<http://perldoc.perl.org/5.14.0/perlunicode.html#User-Defined-Case-Mappings-%28for-serious-hackers-only%29>
字符 编码 输入 和 输出
请参阅编码。
统一 原价 口语 服务支持 Level
以下正则表达式支持的 Unicode 功能列表描述了所有
目前由核心 Perl 直接支持的功能。 对“N 级”的引用和
部分编号参考 Unicode 技术标准 #18,“Unicode 正则
表达式”,第 13 版,2008 年 XNUMX 月。
· 级别 1 - 基本 Unicode 支持
RL1.1 十六进制表示法 - 完成 [1]
RL1.2 属性 - 完成 [2][3]
RL1.2a 兼容性属性 - 完成 [4]
RL1.3 减法和交集 - 实验性 [5]
RL1.4 简单字边界 - 完成 [6]
RL1.5 简单的松散匹配 - 完成 [7]
RL1.6 线边界 - 缺失 [8][9]
RL1.7 补充代码点 - 完成 [10]
[1] "\N{U+...}" 和 "\x{...}"
[2] "\p{...}" "\P{...}"
[3] 不仅支持最小列表,而且支持所有 Unicode 字符属性(参见 Unicode
上面的字符属性)
[4] "\d" "\D" "\s" "\S" "\w" "\W" "\X" "[:支柱:]” "[:^prop:]"
[5] 从 v5.18 开始的实验性功能“(?[...])”实现了这一点。
请参阅 perlre 中的“(?[ ])”。 如果您不想使用实验性功能,您可以
使用以下方法之一:
· 正则表达式前瞻
您可以使用前瞻来模拟类减法。 例如,什么 UTS#18
可以写成
[{Block=希腊语}-[{UNASSIGNED}]]
在 Perl 中可以写成:
(?!\p{未分配})\p{块=希腊语}
(?=\p{已分配})\p{块=希腊语}
但在这个特定的例子中,你可能真的想要
\p{希腊语}
这将匹配已知是希腊文字一部分的指定字符。
· CPAN 模块“Unicode::Regex::Set”
它确实实现了完整的 UTS#18 分组、交集、并集和删除
(减法)语法。
·“用户定义的字符属性”
“+” 表示并集,“-” 表示移除(集差),“&” 表示交集
[6] "\b" "\B"
[7] 请注意,Perl 在匹配中进行完全大小写折叠,而不是简单:
例如,“U+1F88”相当于“U+1F00 U+03B9”,而不仅仅是“U+1F80”。
这种差异主要对某些希腊大写字母很重要
修饰符:Full case-folding 分解字母,而 Simple case-
折叠会将其映射到单个字符。
[8] Perl 将 "\n" 视为开始和结束行分隔符。 Unicode 指定更多
应该这样解释的字符。
它们是:
VT U+000B(C 中的\v)
FF U+000C (\f)
CR U+000D (\r)
内尔 U+0085
LS大学+2028
PSU+2029
正则表达式模式中的“^”和“$”应该匹配所有这些,但是
别。 这些字符也不会,但应该会影响 "<>" $., 和脚本行
号码。
此外,不应在“CRLF”内拆分行(即之间没有空行
“\r”和“\n”)。 对于“CRLF”,试试“:crlf”层(见 PerlIO)。
[9] 但是“Unicode::LineBreak”是可用的。
该模块提供符合 UAX#14 "Unicode Line Breaking
算法”http://www.unicode.org/reports/tr14>.
[10] Perl 中使用的 UTF-8/UTF-EBDDIC 不仅允许“U+10000”到“U+10FFFF”而且
超越“U+10FFFF”
· 级别 2 - 扩展的 Unicode 支持
RL2.1 规范等价物 - 缺失 [10][11]
RL2.2 默认字素簇 - 缺失 [12]
RL2.3 默认字边界 - 完成 [14]
RL2.4 默认松散匹配 - MISSING [15]
RL2.5 名称属性 - 完成
RL2.6 通配符属性 - 缺失
[10] 参见 UAX#15“Unicode 规范化形式”
[11] 有 Unicode::Normalize 但没有集成到正则表达式
[12] 有 \X 和 \b{gcb} 但我们没有“字素簇
模式”
[14] 参见 UAX#29,词边界
[15] 这在第 3.13 章(Unicode 6.0)中有介绍
· 级别 3 - 量身定制的支持
RL3.1 定制标点符号 - 缺失
RL3.2 定制的字素簇 - 缺失 [17][18]
RL3.3 定制词边界 - 缺失
RL3.4 量身定制的松散匹配 - 丢失
RL3.5 定制范围 - 缺失
RL3.6 上下文匹配 - 缺失 [19]
RL3.7 增量匹配 - 丢失
( RL3.8 Unicode 集分享 )
RL3.9 可能的匹配集 - MISSING
RL3.10折叠配对-失踪【20】
RL3.11 子匹配器 - 缺失
[17] 参见 UAX#10“Unicode 整理算法”
[18] 有 Unicode::Collate 但没有集成到正则表达式
[19] 有 (?<=x) 和 (?=x),但是向前看或向后看
应该看到目标子字符串之外
[20] 需要对其他语言特征进行不敏感匹配
比情况; 例如,平假名到片假名,宽和
狭义的、简化的汉字到传统的汉字(见 UTR#30
“字符折叠”)
统一 编码
Unicode 字符被分配给 码 点, 是抽象数。 要使用这些
数字,需要各种编码。
·UTF-8
UTF-8 是一种可变长度(1 到 4 个字节)、与字节顺序无关的编码。 多数情况
在 Perl 的文档中,包括本文档的其他地方,术语“UTF-8”是指
还有“UTF-EBCDIC”。 但在本节中,“UTF-8”仅指用于
ASCII 平台。 它是 7 位 US-ASCII 的超集,所以任何以 ASCII 编码的东西都有
以 UTF-8 编码时的相同表示。
下表来自 Unicode 3.2。
代码点 第 1 个字节 第 2 个字节 第 3 个字节 第 4 个字节
U+0000..U+007F 00..7F
U+0080..U+07FF * C2..DF 80..BF
U+0800..U+0FFF E0 * A0..BF 80..BF
U+1000..U+CFFF E1..EC 80..BF 80..BF
U+D000..U+D7FF ED 80..9F 80..BF
U+D800..U+DFFF +++++ utf16 代理,不合法的 utf8 +++++
U+E000..U+FFFF EE..EF 80..BF 80..BF
U+10000..U+3FFFF F0 * 90..BF 80..BF 80..BF
U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
注意上面几个字节条目之前用“*”标记的间隙。 这些是
由合法的 UTF-8 避免非最短编码引起:技术上可以
UTF-8 以不同的方式对单个代码点进行编码,但这是明确禁止的,
并且应该始终使用尽可能短的编码(这就是 Perl 所做的)。
另一种看待它的方法是通过位:
代码点 第 1 个字节 第 2 个字节 第 3 个字节 第 4 个字节
0aaaaaa 0aaaaaaa
00000bbbbbaaaaaa 110bbbbb 10aaaaaa
ccccbbbbbbbaaaaaa 1110cccc 10bbbbbb 10aaaaaa
00000dddccccccbbbbbbaaaaaa 11110ddd 10cccccc 10bbbbbb 10aaaaaa
如您所见,连续字节都以“10”开头,并且前导位
起始字节告诉编码字符中有多少字节。
原始 UTF-8 规范最多允许 6 个字节,以允许对数字进行编码
高达“0x7FFF_FFFF”。 Perl 继续允许这些,并将其扩展到 13
字节将代码点编码为可以放入 64 位字的内容。 但是,Perl 会
如果您将其中任何一个输出为不可移植,则发出警告; 并在严格的 UTF-8 输入下
协议,它们是被禁止的。
· UTF-EBCDIC
类似于 UTF-8,但 EBCDIC 安全,就像 UTF-8 是 ASCII 安全的那样。 这意味着所有
基本字符(包括所有具有 ASCII 等效值的字符(如“A”、
"0", "%", 等等) 在 EBCDIC 和 UTF-EBCDIC 中相同。)
UTF-EBCDIC 用于 EBCDIC 平台。 最大的 Unicode 代码点占用 5 个字节
来表示(而不是 UTF-4 中的 8 个),Perl 将其扩展到最多 7 个字节以
编码 pod 指向可以放入 32 位字(而不是 13 个字节和一个
UTF-64 中的 8 位字)。
· UTF-16、UTF-16BE、UTF-16LE、代理和“BOM”(字节顺序标记)
以下项目多为参考和一般Unicode知识,Perl
不在内部使用这些结构。
与 UTF-8 一样,UTF-16 是可变宽度编码,但 UTF-8 使用 8 位代码
单位,UTF-16 使用 16 位代码单位。 所有代码点占用 2 或 4 个字节
UTF-16:码点“U+0000..U+FFFF”存储在单个16位单元中,代码
以两个 10000 位为单位指向“U+10..U+16FFFF”。 后一种情况正在使用 代孕,
第一个 16 位单元是 高 代孕,第二个是 低
代孕.
代理是留出的代码点,用于对“U+10000..U+10FFFF”范围进行编码
以 16 位单元为单位的 Unicode 代码点。 这 高 代孕 是范围
“U+D800..U+DBFF”和 低 代孕 是范围“U+DC00..U+DFFF”。 代理人
编码是
$hi = ($uni - 0x10000) / 0x400 + 0xD800;
$lo = ($uni - 0x10000) % 0x400 + 0xDC00;
和解码是
$uni = 0x10000 + ($hi - 0xD800) * 0x400 + ($lo - 0xDC00);
由于 16 位,UTF-16 依赖于字节顺序。 UTF-16 本身可以使用
用于内存计算,但如果需要存储或传输 UTF-16BE
必须选择 (big-endian) 或 UTF-16LE (little-endian) 编码。
这引入了另一个问题:如果你只知道你的数据是 UTF-16,但是
你不知道哪个字节序? 字节顺序标记或“BOM”是一种解决方案
这个。 Unicode 中保留了一个特殊字符作为字节顺序
标记:代码点为“U+FEFF”的字符是“BOM”。
诀窍是,如果您阅读“BOM”,您将知道字节顺序,因为如果它是
在大端平台上编写,您将读取字节“0xFE 0xFF”,但如果它是
在小端平台上编写,您将读取字节“0xFF 0xFE”。 (如果
原始平台以 ASCII 平台 UTF-8 编写,您将读取字节
“0xEF 0xBB 0xBF”。)
这个技巧的工作方式是代码点“U+FFFE”的字符不是
应该在输入流中,所以字节序列“0xFF 0xFE”是明确的
""BOM",以小端格式表示",不能为"U+FFFE",以小端格式表示
大端格式”。
代理在 Unicode 中没有任何意义,除了它们成对使用来表示其他
代码点。 然而,Perl 允许它们在内部单独表示,因为
例如说“CHR(0xD801)”,以便所有代码点,而不仅仅是那些对
开放的互换,是可表示的。 Unicode 确实为它们定义了语义,例如
他们的“General_Category”是“Cs”。 但是因为它们的使用有点危险,Perl
将警告(使用警告类别“代理”,这是“utf8”的子类别)
如果试图做一些事情,比如取一个的小写,或者匹配大小写 -
不敏感,或输出它们。 (但是不要在 5.14 之前在 Perls 上尝试这个。)
· UTF-32、UTF-32BE、UTF-32LE
UTF-32 系列与 UTF-16 系列非常相似,除了单位是
32 位,因此不需要代理方案。 UTF-32 是固定宽度的
编码。 BE 的“BOM”签名是“0x00 0x00 0xFE 0xFF”和“0xFF 0xFE 0x00”
0x00" 代表 LE。
· UCS-2、UCS-4
ISO 10646 标准定义的传统固定宽度编码。 UCS-2 是一个 16 位
编码。 与 UTF-16 不同,UCS-2 不能扩展到“U+FFFF”之外,因为它没有
使用代理。 UCS-4 是一种 32 位编码,在功能上与 UTF-32(
不同之处在于 UCS-4 既不禁止代理也不禁止大于
“0x10_FFFF”)。
·UTF-7
七位安全(非八位)编码,如果传输或存储
不是八位安全的。 由 RFC 2152 定义。
非字符 码 点
Unicode 中留出 66 个代码点作为“非字符代码点”。 这些都有
“未分配”(“Cn”)“General_Category”,并且不会将任何字符分配给任何
他们。 它们是“U+FDD32”和“U+FDEF”之间的 0 个代码点,以及 34 个
代码点:
U+FFFE U+FFFF
U+1FFFE U+1FFFF
U+2FFFE U+2FFFF
...
U+EFFFE U+EFFFF
U+FFFFE U+FFFFE
U+10FFFE U+10FFFF
在 Unicode 7.0 之前,非字符是“被禁止 用于开放式交换
Unicode 文本数据”,以便处理这些流的代码可以使用这些代码点
作为可以与字符数据混合的哨兵,并且总是
与该数据区分开来。 (上面和下一段的强调被添加到
这个文件。)
Unicode 7.0 更改了措辞,使它们是“而不去 建议 用于开放
Unicode 文本数据的交换”。7.0 标准继续说:
“如果在开放交换中收到非字符,则不需要申请
以任何方式解释它。 然而,良好的做法是将其识别为
非字符并采取适当的行动,例如将其替换为“U+FFFD”
替换字符,用于指示文本中的问题。 不建议
简单地从这样的文本中删除非字符代码点,因为潜在的
删除未解释的字符导致的安全问题。 (见一致性条款
第 7 节中的 C3.2,一致性要求和 Unicode 技术报告 #36,
“Unicode 安全注意事项”
<http://www.unicode.org/reports/tr36/#Substituting_for_Ill_Formed_Subsequences>)。”
做这个改动是因为发现各种商业工具,比如编辑器,或者
对于源代码控制之类的事情,已经被编写为他们不会处理
使用这些代码点的程序文件,几乎有效地阻止了它们的使用
完全! 这从来都不是本意。 它们一直是为了在内部可用
一个应用程序或一组协作的应用程序,随意。
如果您正在编写代码,例如编辑器,则应该能够处理任何
Unicode 文本数据,那么你不应该自己使用这些代码点,而是
允许他们输入。 如果你需要哨兵,他们应该是
不是合法的 Unicode。 对于 UTF-8 数据,您可以使用字节 0xC1 和 0xC2 作为标记,如
它们永远不会出现在格式良好的 UTF-8 中。 (UTF-EBCDIC 有等价物)。 你可以
还将您的 Unicode 代码点存储在整数变量中,并使用负值作为
哨兵。
如果您不是在编写这样的工具,那么您是否接受非字符作为输入取决于
你(尽管标准建议你不要)。 如果您进行严格的输入流检查
对于 Perl,这些代码点将继续被禁止。 这是保持落后
兼容性(否则可能会打开潜在的安全漏洞,作为毫无戒心的
假设非字符将在之前被过滤掉而编写的应用程序
得到它,现在可以在没有警告的情况下开始得到它们)。 做严格的检查,
你可以使用层“:encoding('UTF-8')”。
Perl 继续警告(使用警告类别“nonchar”,它是
"utf8") 如果尝试输出非字符。
超越 统一 码 点
Unicode 码位最大为“U+10FFFF”,Unicode 只定义对代码的操作
通过这一点。 但是 Perl 可以处理最大允许的代码点
平台上可用的无符号号码。 但是,Perl 不会从输入中接受这些
除非正在使用松散的规则,否则流将发出警告(使用警告类别
“non_unicode”,它是“utf8”的子类别),如果有的话。
由于这些代码点上没有定义 Unicode 规则,如果一个 Unicode 定义的操作
对它们完成后,Perl 使用我们认为合理的规则,同时一般警告,
使用“non_unicode”类别。 例如,"uc("\x{11_0000}")" 将生成这样一个
警告,返回输入参数作为结果,因为 Perl 定义了大写
每个非 Unicode 代码点都是代码点本身。 (所有情况都在变化
操作,而不仅仅是大写,以这种方式工作。)
在正则表达式中匹配 Unicode 属性的情况,“\p{}”和
"\P{}" 构造,针对这些代码点并不明确,以及这些是如何
随着我们获得经验,处理方式发生了变化。
一种可能性是将与这些代码点的任何匹配视为未定义。 但由于
Perl 没有未定义匹配的概念,它会将其转换为失败或
“错误的”。 这几乎(但不完全)是 Perl 从 v5.14 所做的(当使用这些代码时
点变得普遍可靠)通过 v5.18。 不同的是 Perl 处理所有
"\p{}" 匹配为失败,但所有 "\P{}" 匹配为成功。
这样做的一个问题是它会导致一些意想不到的、令人困惑的结果
情况:
CHR(0x110000) =~ \p{ASCII_Hex_Digit=True} # 在 <= v5.18 上失败
CHR(0x110000) =~ \p{ASCII_Hex_Digit=False} # 失败! 在 <= v5.18
也就是说,它将两个匹配项都视为未定义,并将其转换为 false(引发
每个警告)。 第一种情况是预期的结果,但第二种情况很可能
违反直觉的:“当它们是互补的时,它们怎么可能是假的?” 另一个问题
是实现优化了许多 Unicode 属性匹配到已经
现有的更简单、更快的操作,不会引发警告。 我们选择不放弃
那些帮助绝大多数匹配的优化,只是为了产生警告
用于匹配高于 Unicode 代码点的不太可能发生的事件。
由于这些问题,从v5.20开始,Perl所做的就是处理非Unicode
代码点只是典型的未分配的 Unicode 字符,并相应地匹配。
(注意:Unicode 具有非典型的未分配代码点。例如,它具有非字符代码
分数,以及那些当他们得到分配时,注定要被写入的权利 -
左边,就像阿拉伯语和希伯来语一样。 Perl 假定没有非 Unicode 代码点有任何
非典型属性。)
在大多数情况下,Perl 在匹配高于 Unicode 的代码点时会发出警告
当 "\p{}" 的结果为 "TRUE" 并且 "\P{}" 的结果为 "FALSE" 时,针对 Unicode 属性。
例如:
CHR(0x110000) =~ \p{ASCII_Hex_Digit=True} # 失败,没有警告
CHR(0x110000) =~ \p{ASCII_Hex_Digit=False} # 成功,有警告
在这两个示例中,匹配的字符是非 Unicode,因此 Unicode 不会
定义它应该如何匹配。 它显然不是 ASCII 十六进制数字,所以第一个例子
显然应该失败,而且确实如此,没有任何警告。 但值得商榷的是,第二
示例应该有一个未定义的,因此“假”,结果。 因此对其发出警告。
因此,与早期的 Perls 相比,在更少的情况下发出警告,并且仅当
结果是有争议的。 事实证明,Perl 所做的任何优化都没有
(或可能会发生)导致跳过警告,因此它解决了这两个问题
Perl 早期方法的问题。 受影响的最常用属性
此更改是“\p{Unassigned}”,它是
“\p{General_Category=未分配}”。 从 v5.20 开始,所有非 Unicode 代码点都是
被视为“未分配”。 在早期版本中,匹配失败,因为结果是
视为未定义。
唯一不应该发出警告的地方是如果
优化导致甚至不尝试整个模式匹配。 例如,Perl
可能会发现,对于匹配某个正则表达式模式的字符串,该字符串
必须包含子字符串“foobar”。 在尝试匹配之前,Perl 可能会寻找
该子字符串,如果没有找到,立即使匹配失败而不实际尝试;
因此,即使字符串包含高于 Unicode 的代码点,也不会生成警告。
对于大多数应用程序来说,这种行为比早期的 Perls 更像是“按我的意思去做”。 但
对于需要严格符合 Unicode 的代码,它捕获的问题更少。 所以
有一种额外的操作模式可用于容纳此类代码。 这种模式是
如果正则表达式模式在词法范围内编译,则启用
“non_unicode”警告类已成为致命的,例如:
使用警告 FATAL => "non_unicode"
(见警告)。 在这种操作模式下,Perl 将针对所有匹配项发出警告
针对非 Unicode 代码点(不仅仅是有争议的代码点),它会跳过
可能导致警告不输出的优化。 (目前还不会
如果甚至没有尝试匹配,则发出警告,如上面的“foobar”示例。)
总之,Perl 现在通常将非 Unicode 代码点视为典型的 Unicode 未分配
正则表达式匹配的代码点,仅在有争议时才发出警告
结果应该是什么。 然而,如果这个警告已经成为致命的,它不是
跳过。
所有这一切都有一个例外。 "\p{All}" 看起来像一个 Unicode 属性,但它是一个
Perl 扩展被定义为适用于所有可能的代码点,无论是否为 Unicode,所以
将其与非 Unicode 代码点进行匹配时,不会生成任何警告。 (事先的
到 v5.20,它是“\p{Any}”的同义词,匹配代码点 0 到 0x10FFFF。)
安全性 启示 of 统一
一、阅读Unicode安全注意事项http://www.unicode.org/reports/tr36>.
另外,请注意以下事项:
· 格式错误的 UTF-8
不幸的是,UTF-8 的原始规范留下了一些解释空间
应该从一个输入 Unicode 生成多少字节的编码输出
特点。 严格来说,UTF-8 字节的最短可能序列应该是
生成,因为否则有可能在输入缓冲区溢出
UTF-8 连接的接收端。 Perl 总是生成最短长度的 UTF-8,
并且打开警告时,Perl 将警告非最短长度的 UTF-8 以及其他
畸形,例如代理,它们不是 Unicode 代码点
互换。
· 不习惯的正则表达式模式匹配可能会让你大吃一惊
统一码。 从 Perl 5.14 开始,有几个模式修饰符可用于控制
这称为字符集修饰符。 详细信息在“字符集
perlre 中的修饰符”。
正如在别处讨论的那样,Perl 在两个世界中的每一个中都有一只脚(两只蹄?):
ASCII 和单字节语言环境的旧世界,以及 Unicode 的新世界,升级时
必要的。 如果您的旧代码未明确使用 Unicode,则不会自动切换
Unicode 应该会发生。
统一 in Perl的 on EBCDIC
EBCDIC 平台支持 Unicode。 参见 perlebcdic。
除非专门讨论 ASCII 与 EBCDIC 问题,否则对 UTF-8 的引用
本文档和其他地方的编码应理解为 EBCDIC 上的 UTF-EBCDIC
平台。 请参阅 perlebcdic 中的“Unicode 和 UTF”。
因为 UTF-EBCDIC 与 UTF-8 非常相似,所以大多数差异对您来说是隐藏的;
“使用 utf8”(而不是“使用 utfebcdic”之类的东西)声明脚本在
平台的“原生”8 位 Unicode 编码。 (类似于“:utf8”层。)
当地
请参阅 perllocale 中的“Unicode 和 UTF-8”
在规划婴儿食品行业的工艺要求时,安全性和可靠性是工艺设计中最重要的方面。 统一 儿童在 不 发生
仍然有很多地方可以将 Unicode(以某种编码或另一种编码方式)表示为
参数或作为结果接收,或两者都在 Perl 中,但它不是,尽管 Perl 有
在 Unicode 中输入和输出的广泛方法,以及其他一些“入口点”,如
@ARGV 数组(有时可以解释为 UTF-8)。
以下是此类接口。 另请参阅“Unicode 错误”。 对于所有这些
接口 Perl 当前(从 v5.16.0 开始)简单地将字节字符串都作为参数
和结果,或 UTF-8 字符串(如果已使用(已弃用)“编码”编译指示)。
Perl 在这些情况下不尝试解决 Unicode 角色的原因之一
答案是高度依赖于操作系统和文件系统。
例如,文件名是否可以是 Unicode 以及究竟是哪种编码,是
不完全是一个便携的概念。 对于“qx”和“系统”也类似:
“命令行界面”(以及其中的哪些?)处理 Unicode?
· "chdir", "chmod", "chown", "chroot", "exec", "link", "lstat", "mkdir", "rename",
"rmdir", "stat", "symlink", "truncate", "unlink", "utime", "-X"
· %环境
·“glob”(又名“<*>”)
·“打开”、“opendir”、“sysopen”
·“qx”(又名反引号运算符),“系统”
· "readdir", "readlink"
- “统一码 漏洞”
术语“Unicode 错误”已应用于与代码中的代码点不一致的情况。
“Latin-1 Supplement”块,即在 128 到 255 之间。没有指定语言环境,
与所有其他字符或代码点不同,这些字符可以有非常不同的
语义取决于有效的规则。 (码点大于 255 的字符
强制 Unicode 规则; 而 ASCII 字符的规则在 ASCII 下是相同的
和 Unicode 规则。)
在Unicode规则下,这些大写Latin1字符被解释为Unicode代码点,
这意味着它们具有与 Latin-1 (ISO-8859-1) 和 C1 控件相同的语义。
如“ASCII 规则与 Unicode 规则”中所述,在 ASCII 规则下,它们被视为
是未分配的字符。
这可能会导致意想不到的结果。 例如,一个字符串的语义可以突然
如果将大于 255 的代码点附加到它,则更改规则,这将规则从 ASCII 更改为
统一码。 例如,考虑以下程序及其输出:
$ perl -le'
没有功能“unicode_strings”;
$s1 = "\xC2";
$s2 = "\x{2660}";
对于 ($s1, $s2, $s1.$s2) {
打印 /\w/ || 0;
}
'
0
0
1
如果“s1”和“s2”中都没有“\w”,为什么它们的连接有一个?
这种异常源于 Perl 试图不打扰未使用的旧程序
Unicode,以及 Perl 想要无缝添加 Unicode 支持的愿望。 但结果
原来不是天衣无缝。 (顺便说一句,您可以选择在以下情况时收到警告
这发生。 请参阅“编码::警告”。)
从 Perl v5.12 开始,添加了“使用功能‘unicode_strings’”来解决这个问题
问题。 它会影响这些事情:
· 改变标量的大小写,即使用“uc()”、“ucfirst()”、“lc()”和
"lcfirst()" 或 "\L"、"\U"、"\u" 和 "\l" 在双引号上下文中,例如常规
表达式替换。
在 Perl 5.12.0 开始的“unicode_strings”下,通常使用 Unicode 规则。
请参阅 perlfunc 中的“lc”以获取有关如何与其他各种方法结合使用的详细信息
编译指示。
· 使用无大小写(“/i”)正则表达式匹配。
从 Perl 5.14.0 开始,正则表达式在范围内编译
“unicode_strings”即使在执行或编译成更大的正则时也使用 Unicode 规则
范围外的表达式。
· 匹配正则表达式中的几个属性中的任何一个。
这些属性是“\b”(不带花括号)、“\B”(不带花括号)、“\s”、“\S”、“\w”、
“\W”,以及所有 Posix 字符类 除 “[[:ascii:]]”。
从 Perl 5.14.0 开始,正则表达式在范围内编译
“unicode_strings”即使在执行或编译成更大的正则时也使用 Unicode 规则
范围外的表达式。
· 在“quotemeta”或其内联等价物“\Q”中。
从 Perl 5.16.0 开始,在以下范围内使用一致的引用规则
“unicode_strings”,如 perlfunc 中的“quotemeta”中所述。 在此之前,或在外面
它的范围,在 UTF-127 编码的字符串中没有引用超过 8 的代码点,而是以字节为单位
编码的字符串,128-255 之间的代码点总是被引用。
从上面可以看出,“unicode_strings”的效果增加了几个
Perl 发布。 (而且 Perl 对 Unicode 的支持不断改进;最好使用
最新的可用版本,以便尽可能获得最完整和准确的结果。)
请注意,如果您“使用 5.012”或更高版本,则会自动选择“unicode_strings”。
对于早于上述那些的 Perls,或者当一个字符串被传递给一个函数时
在“unicode_strings”范围之外,请参阅下一节。
强制 统一 in Perl的 (要么 解除强制 统一 in 珀尔)
有时(请参阅“当 Unicode 不发生时”或“Unicode 错误”)有些情况
您只需将字节字符串强制转换为 UTF-8,反之亦然。 标准
模块编码可用于此,或低级调用“utf8::upgrade($bytestring)”
和“utf8::downgrade($utf8string[, FAIL_OK])”。
请注意,如果字符串包含不适合的字符,则“utf8::downgrade()”可能会失败
成一个字节。
在已经处于所需状态的字符串上调用任一函数都是空操作。
“ASCII 规则与 Unicode 规则”给出了字符串使用 Unicode 的所有方式
规则。
运用 统一 in XS
有关 XS 级别的 Unicode 介绍,请参阅 perlguts 中的“Unicode Support”,以及
有关 API 详细信息的 perlapi 中的“Unicode 支持”。
黑客 Perl的 至 工作 on 早期 统一 版本 (用于 非常 严重 黑客 只有)
默认情况下,Perl 带有内置的最新支持的 Unicode 版本,但目标是
允许您更改以使用任何更早的版本。 然而,在 Perls v5.20 和 v5.22 中,
最早可用的版本是 Unicode 5.1。 Perl v5.18 能够处理所有更早的
版本。
从 Unicode 网站下载所需版本的 Unicode 文件
<http://www.unicode.org>)。 这些应该替换现有的文件 库/单核 ,在
Perl 源代码树。 按照中的说明进行操作 自述文件 在该目录中更改一些
他们的名字,然后构建 perl(参见安装)。
移植 码 在 perl-5.6.X
从 5.8 开始的 Perls 具有与 5.6 不同的 Unicode 模型。 在 5.6 中,程序员是
需要使用“utf8”pragma 来声明预期处理的给定范围
Unicode 数据,并且必须确保只有 Unicode 数据才能到达该范围。 如果你
有使用 5.6 的代码,您将需要进行以下一些调整
你的代码。 这些示例的编写使得代码将在 5.6 下继续工作,因此
您应该可以安全地试用它们。
· 应该读或写 UTF-8 的文件句柄
如果 ($] > 5.008) {
binmode $fh, ":encoding(utf8)";
}
· 将传递给某个扩展的标量
无论是“Compress::Zlib”、“Apache::Request”还是任何没有提及的扩展
手册页中的 Unicode,您需要确保去掉 UTF8 标志。 笔记
在撰写本文时(2012 年 XNUMX 月),上述模块还没有
UTF-8 感知。 请检查文档以验证这是否仍然正确。
如果 ($] > 5.008) {
需要编码;
$val = Encode::encode_utf8($val); # 制作八位字节
}
· 我们从扩展中得到的标量
如果您认为标量作为 UTF-8 返回,您很可能需要 UTF8 标志
恢复:
如果 ($] > 5.008) {
需要编码;
$val = 编码::decode_utf8($val);
}
· 同样的事情,如果你真的确定它是 UTF-8
如果 ($] > 5.008) {
需要编码;
编码::_utf8_on($val);
}
· DBI“fetchrow_array”和“fetchrow_hashref”的包装器
当数据库只包含 UTF-8 时,包装函数或方法是一种方便的方法
替换所有“fetchrow_array”和“fetchrow_hashref”调用。 一个包装函数
还可以更轻松地适应数据库驱动程序的未来增强功能。 笔记
在撰写本文时(2012 年 XNUMX 月),DBI 还没有标准化的方法来
处理 UTF-8 数据。 请检查 DBI 文档以验证它是否仍然存在
真实的。
子 fetchrow {
# $what 是 fetchrow_{array,hashref} 之一
我的($self, $sth, $what) = @_;
如果 ($] < 5.008) {
返回 $sth->$what;
} {
需要编码;
如果(想要数组){
我的@arr = $sth->$what;
对于(@arr){
定义 && /[^\000-\177]/ && 编码::_utf8_on($_);
}
返回@arr;
} {
我的 $ret = $sth->$what;
如果(参考 $ret){
对于我的 $k (keys %$ret) {
定义
&& /[^\000-\177]/
&& Encode::_utf8_on($_) for $ret->{$k};
}
返回 $ret;
} {
为 $ret 定义 && /[^\000-\177]/ && Encode::_utf8_on($_);
返回 $ret;
}
}
}
}
· 你知道的一个大标量只能包含ASCII
仅包含 ASCII 并标记为 UTF-8 的标量有时会拖累您的
程序。 如果您认识到这种情况,只需删除 UTF8 标志:
utf8::downgrade($val) 如果 $] > 5.008;
使用 onworks.net 服务在线使用 perlunicode