这是 perllocale 命令,可以使用我们的多个免费在线工作站之一在 OnWorks 免费托管服务提供商中运行,例如 Ubuntu Online、Fedora Online、Windows 在线模拟器或 MAC OS 在线模拟器
程序:
您的姓名
perllocale - Perl 语言环境处理(国际化和本地化)
商品描述
最初有 ASCII,即“美国信息标准代码”
Interchange”,这对美国人来说非常有效,他们的英文字母和美元——
计价货币。 但即使对其他说英语的人来说也不是很好,他们
可以使用不同的货币,例如英镑(作为该货币的符号
不是 ASCII); 对于世界上成千上万的人来说,这绝对是不够的
其他语言。
为了解决这些缺陷,发明了语言环境的概念(正式的 ISO C、
XPG4、POSIX 1.c“语言环境系统”)。 应用程序曾经和正在编写使用
区域机制。 提出此类申请的过程考虑到其
用户在这类事情上的偏好称为 国际化 (经常
缩写为 i18n); 告诉这样的应用程序关于一组特定的首选项是
被称为 本土化 (l10n).
Perl 已扩展为支持区域设置系统。 这是每个应用程序控制的
通过使用一个编译指示、一个函数调用和几个环境变量。
不幸的是,该设计存在不少缺陷(通常情况下,
实现)的语言环境。 Unicode 被发明(见 perlitut 的介绍
那)部分是为了解决这些设计缺陷,如今,有一系列
“UTF-8 语言环境”,基于 Unicode。 这些是字符集为 Unicode 的语言环境,
以 UTF-8 编码。 从 v5.20 开始,Perl 完全支持 UTF-8 语言环境,除了
排序和字符串比较。 (对这些使用 Unicode::Collate。)Perl 继续
也支持旧的非 UTF-8 语言环境。 目前没有 UTF-8 语言环境
EBCDIC 平台。
(Unicode 还创建了“CLDR”,即“通用语言环境数据存储库”,
<http://cldr.unicode.org/> 其中包含的信息类型多于
POSIX 语言环境系统。 在撰写本文时,还没有 CPAN 模块
提供对这种 XML 编码数据的访问。 但是,它的许多语言环境都有 POSIX-
仅提取数据,并且在 UTF-8 语言环境中可用
<http://unicode.org/Public/cldr/latest/>.)
什么是 IS A 本地
区域设置是一组数据,描述了不同社区如何在各个方面
世界对他们的世界进行分类。 这些类别分为以下类型
(其中一些包括一个简短的说明):
类别“LC_NUMERIC”:数字格式
这表明应该如何格式化数字以提高人类可读性,例如
用作小数点的字符。
类别“LC_MONETARY”:货币金额的格式
类别“LC_TIME”:日期/时间格式
类别“LC_MESSAGES”:错误和其他消息
这仅被 Perl 用于通过 $! 访问操作系统错误消息。
和 $^E。
类别“LC_COLLATE”:整理
这表示用于比较和排序的字母顺序。 拉丁语
字母,例如“b”,通常跟在“a”之后。
类别“LC_CTYPE”:字符类型
例如,这表示字符是否为大写字母。
其他类别
一些平台有其他类别,处理诸如度量单位之类的事情
和纸张尺寸。 这些都不是 Perl 直接使用的,而是外部操作
Perl 交互可能会用到这些。 请参阅下面的“不在“使用语言环境”的范围内。
Perl 使用的类别的更多详细信息在下面的“LOCALE CATEGORIES”中给出。
总之,这些类别在能够定制单个程序方面大有帮助
在许多不同的地方运行。 但是有不足之处,所以继续阅读。
准备中 TO 用途 地区
除非特别要求,否则 Perl 本身(在 POSIX 模块之外)不会使用语言环境
到(但再次注意 Perl 可能会与使用它们的代码交互)。 即使有
这样的要求, 所有 必须符合以下条件才能正常工作:
· 您的 操作 系统 必须 支持 这些因素包括原料奶的可用性以及达到必要粉末质量水平所需的工艺。 当地 系统. 如果是这样,你应该找到
“setlocale()”函数是其 C 库的文档部分。
· 定义 HPMC胶囊 当地 这 使用 必须 be 安装. 你,或者你的系统
管理员,必须确保是这种情况。 可用的语言环境,
它们的保存位置和安装方式各不相同
从系统到系统。 某些系统仅提供少数硬接线区域设置,并且不提供
允许添加更多。 其他人允许您添加由
系统供应商。 还有一些允许您或系统管理员定义和添加
任意语言环境。 (您可能需要要求您的供应商提供罐头语言环境
不随您的操作系统一起提供。)请阅读您的系统文档以了解
进一步的照明。
· Perl的 必须 相信 这 这些因素包括原料奶的可用性以及达到必要粉末质量水平所需的工艺。 当地 系统 is 支持的. 如果是这样,“perl
-V:d_setlocale" 会说 "d_setlocale" 的值是 "define"。
如果您希望 Perl 应用程序根据特定的方式处理和呈现您的数据
区域设置,应用程序代码应包括“使用区域设置”pragma(请参阅“使用区域设置”
pragma") 在适当的情况下,以及 at 最少 一种 以下各项必须为真:
1. 这个 地区决定 环境 变量 (见 “环境”) 必须 be 正确地 集
up 在应用程序启动时,由您自己或设置的任何人
您的系统账户; 或者
2. 这个 应用 必须 集 它的 己 当地 使用“setlocale”中描述的方法
功能”。
使用 地区
这个 “用 地区” 编译
默认情况下,Perl 本身(在 POSIX 模块之外)忽略当前的语言环境。 这
“use locale” pragma 告诉 Perl 对某些操作使用当前的语言环境。 开始于
v5.16,此 pragma 有一些可选参数,如下所述,用于限制哪些
操作受其影响。
当前区域设置在执行时由 设置区域设置() 如下面所描述的。 如果说
程序执行过程中尚未调用函数,当前
区域设置是由在开始时生效的“环境”确定的
程序。 如果没有有效的环境,则当前语言环境是任何系统
默认已设置为。 在 POSIX 系统上,可能但不一定是“C”
语言环境。 在 Windows 上,默认设置是通过计算机的
“控制面板->区域和语言选项”(或其当前等效项)。
受语言环境影响的操作是:
不 中 这些因素包括原料奶的可用性以及达到必要粉末质量水平所需的工艺。 范围 of “用 地区”
只有某些源自 Perl 之外的操作会受到影响,如下所示:
· 在 Perl 之外执行类似操作时使用当前语言环境
系统() 或 qx//,如果这些操作是区域敏感的。
· Perl 还允许通过 POSIX 模块访问各种 C 库函数。
其中一些功能总是受当前语言环境的影响。 例如,
"POSIX::strftime()" 使用 "LC_TIME"; "POSIX::strtod()" 使用 "LC_NUMERIC";
"POSIX::strcoll()" 和 "POSIX::strxfrm()" 使用 "LC_COLLATE"; 和性格
像“POSIX::isalnum()”这样的分类函数使用“LC_CTYPE”。 所有这些
函数将根据当前的底层语言环境运行,即使那样
语言环境不暴露于 Perl 空间。
· 所有类别的 XS 模块,但“LC_NUMERIC”获取底层语言环境,以及
因此,它们调用的任何 C 库函数都将使用该底层语言环境。 更多
讨论,请参阅 perlxs 中的“CAVEATS”。
请注意,所有 C 程序(包括用 C 编写的 perl 解释器)
总是有一个底层的语言环境。 该语言环境是“C”语言环境,除非被一个
拨电至 设置区域设置(). 当 Perl 启动时,它会将底层语言环境更改为
这由“环境”表示。 使用 POSIX 模块或编写 XS 时
代码,重要的是要记住底层语言环境可能是
除了“C”,即使程序没有明确改变它。
缠绵 影响 of “用 地区”
在“使用区域设置”范围内设置的某些 Perl 操作保留了
即使超出范围也有影响。 这些包括:
· 输出格式 写() 由较早的格式声明确定
(perlfunc 中的“格式”),所以输出是否受语言环境影响是
由“格式()”是否在“使用区域设置”的范围内确定,而不是是否
“写()”是。
· 正则表达式模式可以使用 qr// 与实际匹配进行编译
推迟到以后。 同样,编译是否在内部完成
确定匹配行为的“使用区域设置”的范围,而不是匹配
是否在这样的范围内完成。
下 ““用 语言环境";"
· 以上所有操作
· 格式 声明 (perlfunc 中的“格式”),因此任何后续的“write()”使用
“LC_NUMERIC”。
· 字符串化 和 产量 使用“LC_NUMERIC”。 这些包括结果
“print()”、“printf()”、“say()”和“sprintf()”。
· 这个 对照 运营商 (“lt”、“le”、“cmp”、“ge”和“gt”)使用“LC_COLLATE”。
如果在没有显式比较函数的情况下使用“sort()”也会受到影响,因为
它默认使用“cmp”。
请注意: "eq" 和 "ne" 不受语言环境的影响:它们总是逐个字符地执行
比较它们的标量操作数。 更重要的是,如果“cmp”发现它的
根据当前指定的整理顺序,操作数相等
语言环境,它继续执行一个逐个字符的比较,并且只返回 0
(相等)如果操作数是 char-for-char 相同的。 如果你真的想知道
两个字符串——“eq”和“cmp”可能认为不同——是否相等
至于语言环境中的整理,请参阅“Category
“LC_COLLATE”:整理”。
· 原价 表达式 和 案例修改 功能 ("uc()", "lc()", "ucfirst()",
和“lcfirst()”)使用“LC_CTYPE”
· 这个 变量 $! (及其同义词 $ERRNO 和 $OS_ERROR) 和 $^E (及其同义词
$EXTENDED_OS_ERROR) 用作字符串时使用“LC_MESSAGES”。
使用“无语言环境”pragma 或在到达结束时恢复默认行为
封闭“使用语言环境”的块。 请注意,“使用区域设置”调用可能是嵌套的,并且
内部作用域内有效的内容最终将恢复到外部作用域的规则
的内部范围。
任何使用区域设置信息的操作的字符串结果都被污染了,因为它是
区域设置可能不可信。 参见“安全”。
从 Perl v5.16 开始,以非常有限的方式开始,更普遍的是在 v5.22 中,您可以
限制此特定实例启用的类别
pragma 通过向其添加参数。 例如,
使用语言环境 qw(:ctype :numeric);
仅在其范围内的那些操作(如上所列)中启用区域设置感知
受“LC_CTYPE”和“LC_NUMERIC”影响。
可能的类别有:":collate"、":ctype"、":messages"、":monetary"、":numeric"、
":time" 和伪类别 ":characters"(如下所述)。
因此你可以说
使用语言环境':messages';
而且只有 $! 和 $^E 将知道区域设置。 其他一切都不受影响。
由于 Perl 当前不对“LC_MONETARY”类别执行任何操作,因此指定
":monetary" 实际上什么也没做。 有些系统还有其他类别,例如
“LC_PAPER_SIZE”,但 Perl 也对它们一无所知,也没有办法
在此 pragma 的参数中指定它们。
您还可以轻松地说使用除一个以外的所有类别,例如,
使用语言环境 ':!ctype';
使用语言环境 ':not_ctype';
这两者都意味着启用除“LC_CTYPE”之外的所有类别的区域设置感知。 只有一个
如果类别参数是否定形式,则可以在“使用区域设置”中指定类别参数。
在 v5.22 之前,只有一种带参数的 pragma 形式可用:
使用语言环境 ':not_characters';
(并且您必须说“not_”;您不能使用“!”形式)。 这个伪类是一个
指定 ":collate" 和 ":ctype" 的简写。 因此,在否定形式中,它是
几乎和说的一样
使用语言环境 qw(:messages :monetary :numeric :time);
我们使用术语“nearly”,因为“:not_characters”也会打开
在其范围内“使用功能'unicode_strings'”。 这种形式在 v5.20 中不太有用,并且
稍后,并在“Unicode 和 UTF-8”中进行了完整的描述,但简而言之,它告诉 Perl 不要
使用语言环境定义的字符部分,即“LC_CTYPE”和
“LC_COLLATE”类别。 相反,它将使用本机字符集(扩展为
统一码)。 使用此参数时,您负责获取外部
字符集转换为本地/Unicode 字符集(如果是
越来越流行的 UTF-8 语言环境之一)。 有一些方便的方法可以做到这一点,
如“Unicode 和 UTF-8”中所述。
这个 设置区域 function
您可以在运行时使用“POSIX::setlocale()”随时切换区域设置
功能:
# 从 POSIX 模块导入语言环境处理工具集。
# 本例使用: setlocale -- 函数调用
# LC_CTYPE -- 解释如下
#(显示操作成功/失败的测试是
# 在这些例子中省略以避免分散注意力
# 观点)
使用 POSIX qw(locale_h);
使用语言环境;
我的 $old_locale;
# 查询并保存旧的语言环境
$old_locale = setlocale(LC_CTYPE);
setlocale(LC_CTYPE,“fr_CA.ISO8859-1”);
# LC_CTYPE 现在在语言环境“法国,加拿大,代码集 ISO 8859-1”
设置区域设置(LC_CTYPE,“”);
# LC_CTYPE 现在重置为由
# LC_ALL/LC_CTYPE/LANG 环境变量,或者给系统
# 默认。 请参阅下面的文档。
# 恢复旧的语言环境
setlocale(LC_CTYPE,$old_locale);
这会同时影响程序的所有线程,因此使用起来可能会有问题
线程应用程序中的语言环境,除非有一个适用于所有语言的语言环境
线程。
“setlocale()”的第一个参数给出了 类别,第二个 当地。 该
category 告诉您要在数据处理的哪个方面应用特定于区域设置的规则。
类别名称在“LOCALE CATEGORIES”和“ENVIRONMENT”中讨论。 语言环境是
对应于特定的定制信息集合的名称
语言、国家或地区和代码集的组合。 继续阅读以获取有关
语言环境的命名:并非所有系统都像示例中那样命名语言环境。
如果没有提供第二个参数并且类别不是“LC_ALL”,则
函数返回一个字符串,命名类别的当前语言环境。 你可以用这个
value 作为后续调用“setlocale()”的第二个参数, 但是 在某些平台上
字符串是不透明的,不是大多数人能够破译的东西
区域设置的意思。
如果未提供第二个参数且类别为“LC_ALL”,则结果为
依赖于实现。 它可能是一串连接的语言环境名称(分隔符也
实现相关)或单个语言环境名称。 请咨询您的 设置区域(3) 男人
页。
如果给出了第二个参数并且它对应于有效的语言环境,则
category 设置为该值,并且该函数返回当前的区域设置值。 你
然后可以在另一个对“setlocale()”的调用中使用它。 (在一些实现中,
返回值有时可能与你作为第二个参数给出的值不同——想想
它作为您提供的值的别名。)
如示例所示,如果第二个参数是空字符串,则类别的语言环境为
返回到相应环境变量指定的默认值。 一般来说,
这导致返回到 Perl 启动时生效的默认值:更改为
应用程序在启动后所做的环境可能会或可能不会被注意到,这取决于
在您系统的 C 库中。
请注意,当指定了不包括所有类别的“使用区域设置”形式时,
Perl 忽略排除的类别。
如果“set_locale()”由于某种原因失败(例如,尝试设置为语言环境
系统未知),类别的语言环境未更改,并且函数
返回“undef”。
有关类别的更多信息,请咨询 设置区域(3)。
查找 当地
对于您系统中可用的语言环境,另请咨询 设置区域(3)看是否导致
可用语言环境列表(搜索 SEE ALSO 部分)。 如果失败,请尝试
以下命令行:
locale -a
信息
ls /usr/lib/nls/loc
ls /usr/lib/语言环境
ls /usr/lib/nls
ls /usr/share/语言环境
看看他们是否列出了类似这些的东西
en_US.ISO8859-1 de_DE.ISO8859-1 ru_RU.ISO8859-5
en_US.iso88591 de_DE.iso88591 ru_RU.iso88595
en_US de_DE ru_RU
恩德如
英语 德语 俄语
英语.iso88591 德语.iso88591 俄语.iso88595
English.roman8 russian.koi8r
遗憾的是,即使“setlocale()”的调用接口已经标准化,
区域设置和配置所在的目录尚未存在。 基本形式
名字是 语言_领土.代码集,但后面的部分 language 是不
始终存在。 这 language 和 国家 通常来自标准 ISO 3166 和 ISO
639, 国家和世界语言的两个字母缩写,
分别。 的 代码集 部分经常提到一些 ISO 8859 字符集,拉丁语
代码集。 例如,“ISO 8859-1”就是所谓的“西欧代码集”,它可以
用于对大多数西欧语言进行充分编码。 再次,有几个
甚至写出那个标准的名称的方法。 可悲。
值得特别提及的两个特殊语言环境:“C”和“POSIX”。 目前这些是
实际上相同的语言环境:区别主要在于第一个是由
C 标准,第二个由 POSIX 标准。 他们定义了 默认 当地 在其中
每个程序都在其环境中缺少语言环境信息的情况下启动。 (这
默认 默认语言环境,如果你愿意。)它的语言是(美国)英语,它的
字符代码集 ASCII 或极少数情况下的超集(例如“DEC Multinational
字符集(DEC-MCS)”)。 警告. 某些供应商提供的 C 语言环境可能不
实际上完全符合 C 标准的要求。 所以要小心。
注意:并非所有系统都具有“POSIX”语言环境(并非所有系统都符合 POSIX 标准),因此
当您需要明确指定此默认语言环境时,请使用“C”。
本地 问题
您可能会在 Perl 启动时遇到以下警告消息:
perl:警告:设置区域设置失败。
perl:警告:请检查您的区域设置:
LC_ALL = "En_US",
LANG =(未设置)
支持并安装在您的系统上。
perl:警告:回退到标准语言环境(“C”)。
这意味着您的语言环境设置已将“LC_ALL”设置为“En_US”并且 LANG 存在但具有
没有价值。 Perl 试图相信你,但不能。 相反,Perl 放弃并退回
到“C”语言环境,无论如何都应该工作的默认语言环境。 (在
Windows,它首先尝试回退到系统默认语言环境。)这通常意味着
您的语言环境设置错误,他们提到了您的系统从未听说过的语言环境,或者
您系统中的语言环境安装有问题(例如,某些系统文件是
损坏或丢失)。 这些问题有快速和临时的修复方法,以及
更彻底和持久的修复。
测试与验证 HPMC胶囊 破 当地
如果您从源代码构建 Perl,则 Perl 测试套件文件 库/语言环境.t 可用于
测试系统上的语言环境。 设置环境变量“PERL_DEBUG_FULL_TEST”
to 1 将导致它输出详细的结果。 例如,在 Linux 上,你可以说
PERL_DEBUG_FULL_TEST=1 ./perl -T -Ilib lib/locale.t > locale.log 2>&1
除了许多其他测试之外,它还会测试它在您的系统上找到的每个区域设置,看看它们是否
符合POSIX标准。 如果有任何错误,它将在结尾处包含一个摘要
哪些语言环境的输出通过了所有测试,哪些失败了,以及为什么。
暂时 定影 当地 问题
两个最快的修复方法是让 Perl 对任何区域设置不一致保持沉默
或者在默认语言环境“C”下运行 Perl。
Perl 关于语言环境问题的抱怨可以通过设置环境变量来消除
"PERL_BADLANG" 为 "0" 或 ""。 这种方法真的只是扫了地毯下的问题:
你告诉 Perl 闭嘴,即使 Perl 发现有问题。 不要惊讶
如果稍后某些依赖于语言环境的行为不端。
通过将环境变量“LC_ALL”设置为“C”,Perl 可以在“C”语言环境下运行。
这种方法可能比“PERL_BADLANG”方法更文明一点,但是设置
“LC_ALL”(或其他语言环境变量)也可能影响其他程序,而不仅仅是 Perl。 在
特别是,从 Perl 内部运行的外部程序会看到这些变化。 如果你使
新设置永久(继续阅读),您运行的所有程序都会看到更改。 看
“ENVIRONMENT” 相关环境变量的完整列表和“USING LOCALES”
它们在 Perl 中的效果。 其他程序中的效果很容易推断出来。 例如,
变量“LC_COLLATE”很可能会影响您的 分类 程序(或任何程序
在您的系统中按字母顺序排列“记录”被称为)。
您可以测试临时更改这些变量,如果新设置似乎
帮助,将这些设置放入您的 shell 启动文件中。 查阅您当地的文档
确切的细节。 对于 Bourne-like shell (sh, KSH, 打坏, zsh的):
LC_ALL=en_US.ISO8859-1
导出 LC_ALL
这假设我们使用上面讨论的命令看到了语言环境“en_US.ISO8859-1”。
我们决定尝试代替上述错误的语言环境“En_US”——以及在 Cshish shell 中
(长山壕, tcsh的)
setenv LC_ALL en_US.ISO8859-1
或者如果你有“env”应用程序,你可以做(在任何shell中)
环境 LC_ALL=en_US.ISO8859-1 perl ...
如果您不知道自己拥有什么 shell,请咨询您当地的帮助台或同等机构。
永久 定影 当地 问题
较慢但更好的修复是当您可以自己修复
您自己的环境变量配置错误。 错误的(sing)配置
整个系统的语言环境通常需要您友好的系统管理员的帮助。
首先,请参阅本文档前面关于“查找语言环境”的内容。 这告诉如何找到哪个
您的系统上确实支持语言环境——更重要的是,安装了语言环境。 在我们的
示例错误信息,影响语言环境的环境变量按顺序列出
重要性降低(和未设置的变量无关紧要)。 因此,拥有 LC_ALL
设置为“En_US”一定是错误的选择,如错误消息所示。 第一次尝试
修复首先列出的区域设置。
其次,如果使用列出的命令,你会看到一些东西 究竟 (前缀匹配不
计数和大小写通常计数)像没有引号的“En_US”,那么你应该没问题
因为您使用的区域设置名称应该在您的系统中安装并可用。
在这种情况下,请参阅“永久修复系统的语言环境配置”。
永久 定影 您的 系统 当地 配置
这是当您看到以下内容时:
perl:警告:请检查您的区域设置:
LC_ALL = "En_US",
LANG =(未设置)
支持并安装在您的系统上。
但随后无法看到上述命令列出的“En_US”。 你可能会看到
诸如“en_US.ISO8859-1”之类的东西,但这不一样。 在这种情况下,尝试在
您可以列出并且以某种方式与您尝试过的内容相匹配的语言环境。 匹配规则
区域名称有点模糊,因为这方面的标准化很弱。 又见
关于一般规则的“查找语言环境”。
定影 系统 当地 配置
联系系统管理员(最好是您自己的管理员)并报告确切的错误消息
你得到了,并要求他们阅读你现在正在阅读的同一份文档。 他们应该是
能够检查语言环境配置是否有问题
系统。 不幸的是,“查找语言环境”部分对确切的
命令和位置,因为这些东西不是那么标准化。
这个 本地转换 function
"POSIX::localeconv()" 函数允许您获取语言环境相关的详细信息
由当前底层“LC_NUMERIC”指定的数字格式信息和
“LC_MONETARY”语言环境(无论是否在“使用语言环境”范围内调用
或不)。 (如果您只想要特定类别的当前语言环境的名称,请使用
带有单个参数的“POSIX::setlocale()”——请参阅“setlocale 函数”。)
使用 POSIX qw(locale_h);
# 获取对区域设置相关信息散列的引用
$locale_values = localeconv();
# 输出排序的值列表
for(排序键 %$locale_values){
printf "%-20s = %s\n", $_, $locale_values->{$_}
}
“localeconv()”不带参数,并返回 a 参考 至 一个哈希。 这个的关键
hash 是用于格式化的变量名称,例如“decimal_point”和“thousands_sep”。 这
值是相应的,呃,值。 有关更长的示例,请参阅 POSIX 中的“localeconv”
列出实现可能提供的类别; 有些提供更多
和其他人更少。 您不需要明确的“使用语言环境”,因为“localeconv()”总是
观察当前的语言环境。
这是一个头脑简单的示例程序,它将其命令行参数重写为
在当前语言环境中正确格式化的整数:
使用 POSIX qw(locale_h);
# 获取一些locale的数字格式参数
我的 ($thousands_sep, $grouping) =
@{localeconv()}{'thousands_sep', '分组'};
# 如果缺少值,则应用默认值
$thousands_sep = ',' 除非 $thousands_sep;
# grouping 和 mon_grouping 是打包列表
# 小整数(字符)告诉
# 分组(thousand_seps 和 mon_thousand_seps
# 是数字的组分隔符)和
# 货币数量。 整数的含义:
# 255 表示不再分组,0 表示重复
# 前面的分组,1-254 表示使用那个
# 作为当前分组。 分组来自
# 从右到左(从低到高的数字)。 在里面
# 下面我们从不使用任何东西来作弊
# 除了第一个分组(无论是什么)。
如果($分组){
@grouping = unpack("C*", $grouping);
} {
@分组=(3);
}
# 格式化当前语言环境的命令行参数
对于(@ARGV){
$_ = 整数; # 切掉非整数部分
1 同时
s/(\d)(\d{$grouping[0]}($|$thousands_sep))/$1$thousands_sep$2/;
打印“$_”;
}
打印“\n”;
请注意,如果平台没有可用的“LC_NUMERIC”和/或“LC_MONETARY”,或者
启用,哈希的相应元素将丢失。
I18N::语言信息
查询语言环境相关信息的另一个接口是
"I18N::Langinfo::langinfo()" 函数,至少在类 Unix 系统和 VMS 中可用。
以下示例将导入“langinfo()”函数本身和三个常量以
用作“langinfo()”的参数:一周中缩写的第一天的常量
(编号从星期日开始= 1)和两个更多的常数用于肯定和
当前语言环境中是/否问题的否定答案。
使用 I18N::Langinfo qw(langinfo ABDAY_1 YESSTR NOSTR);
我的 ($abday_1, $yesstr, $nostr)
= 地图 { langinfo } qw(ABDAY_1 YESSTR NOSTR);
打印“$abday_1?[$yesstr/$nostr]”;
换句话说,在“C”(或英语)语言环境中,上面可能会打印一些东西
喜欢:
太阳? [是/否]
有关更多信息,请参阅 I18N::Langinfo。
本地 新闻概览
以下小节描述了基本的语言环境类别。 除了这些,一些
组合类别允许一次操作多个基本类别。 看
“环境”对这些进行了讨论。
分类 “LC_COLLATE”: 整理
在包括排序规则的“使用区域设置”形式的范围内,Perl 查找
“LC_COLLATE”环境变量,用于确定应用程序的整理概念
(排序)字符。 例如,在拉丁字母中,“b”跟在“a”之后,但是在哪里
“a”和“aa”属于? 在英语中,“color”跟在“chocolate”之后,那么在
传统的西班牙语?
以下排序规则都很有意义,如果您“使用语言环境”,您可能会遇到其中任何一个排序规则。
ABCDE ABCDE
A a B b C c D d E e
a A b B c C d D e E
ABCDE
这是一个代码片段,用于说明当前语言环境中的“单词”字符是什么,即
语言环境的顺序:
使用语言环境;
打印 +(sort grep /\w/, map { chr } 0..255), "\n";
如果您明确指出,请将其与您看到的字符及其顺序进行比较
应该忽略语言环境:
没有语言环境;
打印 +(sort grep /\w/, map { chr } 0..255), "\n";
这种机器原生排序规则(除非出现“使用语言环境”,否则您会得到
在同一块中较早的位置)必须用于对原始二进制数据进行排序,而 locale-
第一个示例的相关排序规则对于自然文本很有用。
如“使用本地化”中所述,“cmp”在以下情况下根据当前的排序规则语言环境进行比较
“使用区域设置”是有效的,但回退到逐字符比较的字符串
语言环境说是平等的。 如果你不想这个秋天,你可以使用“POSIX::strcoll()”——
背部:
使用 POSIX qw(strcoll);
$equal_in_locale =
!strcoll("忽略空格和大小写", "SpaceAndCaseIgnored");
如果校对语言环境指定了类似字典的排序,则 $equal_in_locale 将为真
完全忽略空格字符并且折叠大小写。
Perl 当前仅支持“LC_COLLATE”的单字节语言环境。 这意味着一个
UTF-8 语言环境可能只会为您提供机器本机排序。 使用 Unicode::Collate
Unicode 整理算法的完整实现。
如果您有一个字符串要检查“语言环境中的相等性”
其他几个,你可能认为你可以通过使用获得一点效率
"POSIX::strxfrm()" 与 "eq" 结合使用:
使用 POSIX qw(strxfrm);
$xfrm_string = strxfrm("混合大小写字符串");
打印“语言环境排序忽略空格\n”
if $xfrm_string eq strxfrm("Mixed-casestring");
打印“语言环境整理忽略连字符\n”
if $xfrm_string eq strxfrm("Mixedcase string");
打印“语言环境排序忽略大小写\n”
if $xfrm_string eq strxfrm("mixed-case string");
“strxfrm()”接受一个字符串并将其映射到一个转换后的字符串中,以便在逐个字符中使用
在整理期间与其他转换后的字符串进行比较。 “在引擎盖下”,语言环境-
受影响的 Perl 比较操作符为两个操作数调用“strxfrm()”,然后执行一个 char-by-
转换后的字符串的字符比较。 通过显式调用“strxfrm()”并使用
不受语言环境影响的比较,该示例尝试保存一些转换。
但实际上,它并没有保存任何东西:Perl 魔术(请参阅 perlguts 中的“魔术变量”)
在比较中第一次需要时创建字符串的转换版本,
然后保留此版本以备再次需要时使用。 一个例子重写了简单的
使用“cmp”的方式运行速度也差不多。 它还处理嵌入的空字符
字符串; 如果您直接调用“strxfrm()”,它会将它找到的第一个空值视为
终结者。 不要指望它产生的转换后的字符串是可移植的
系统——甚至从您的操作系统的一个版本到下一个版本。 简而言之,不要
直接调用“strxfrm()”:让 Perl 为你做。
注意:其中一些示例中未显示“使用区域设置”,因为不需要它:
"strcoll()" 和 "strxfrm()" 是使用标准系统提供的 POSIX 函数
“libc”函数始终遵循当前的“LC_COLLATE”语言环境。
分类 “LC_CTYPE”: 字符 类型
在包含“LC_CTYPE”的“使用语言环境”形式的范围内,Perl 遵守“LC_CTYPE”
区域设置。 这控制了应用程序关于哪些字符是
字母、数字、标点符号、 等。. 这会影响 Perl 的 "\w" 正则表达式
元符号,代表字母数字字符——即字母、数字和
平台的原生下划线。 (有关常规的更多信息,请咨询 perlre
表达式。)感谢“LC_CTYPE”,根据您的语言环境设置,字符如
“ae”、“`”、“ss”和“o”可以理解为“\w”字符。 也会影响事情
比如“\s”、“\D”和POSIX字符类,比如“[[:graph:]]”。 (看
perlrecharclass 有关所有这些的更多信息。)
“LC_CTYPE”语言环境还提供了用于音译字符之间的映射
小写和大写。 这会影响大小写映射函数——“fc()”、“lc()”、
“lcfirst()”、“uc()”和“ucfirst()”; 带有 "\F", "\l", "\L" 的 case-mapping 插值,
双引号字符串中的“\u”或“\U”和“s///”替换; 和大小写无关
使用“i”修饰符的正则表达式模式匹配。
最后,“LC_CTYPE”影响(不推荐使用的)POSIX 字符类测试
函数——“POSIX::isalpha()”、“POSIX::islower()”等等。 例如,如果您移动
从“C”语言环境到 7 位 ISO 646 语言环境,您可能会发现——可能出乎您的意料——
“|” 从“POSIX::ispunct()”类移动到“POSIX::isalpha()”。 不幸的是,这
给正则表达式带来了很大的问题。 “|” 仍然意味着交替,即使它
匹配“\w”。 从 v5.22 开始,切换这样的语言环境时会发出警告
进入。 更多细节在下面的几个段落中给出。
从 v5.20 开始,Perl 支持“LC_CTYPE”的 UTF-8 语言环境,否则仅支持 Perl
支持单字节语言环境,例如 ISO 8859 系列。 这意味着宽字符
语言环境,例如亚洲语言,没有得到很好的支持。 (如果平台有
Perl 检测这种语言环境的能力,从 Perl v5.22 开始,Perl 会发出警告,
默认启用,使用“语言环境”警告类别,每当这样的语言环境被切换时
进入。)UTF-8 语言环境支持实际上是 POSIX 语言环境的超集,因为它是
真正完整的 Unicode 行为,好像根本没有“LC_CTYPE”语言环境有效(除了
污染; 见“安全”)。 POSIX 语言环境,甚至 UTF-8 语言环境,都缺乏某些概念
在 Unicode 中,例如改变字符的大小写可以扩展为更多的想法
比一个字符。 UTF-8 语言环境中的 Perl 将为您提供扩展。 之前
v5.20,Perl 在某些平台上处理 UTF-8 语言环境,例如 ISO 8859-1 语言环境,有些
限制,而在其他平台上更像是“C”语言环境。 对于版本 v5.16 和
v5.18,“使用语言环境'not_characters”可以用作解决此问题的方法(请参阅“Unicode
和 UTF-8”)。
请注意,有很多事情不受当前语言环境的影响。 任何
文字字符是给定平台的本地字符。 因此'A'的意思是
ASCII 平台上代码点 65 处的字符,EBCDIC 上 193 处的字符。 那可能是也可能不是
当前语言环境中的“A”,如果该语言环境甚至具有“A”。 同样的,所有的逃避
特定字符的序列,例如“\n”,始终表示平台的本机
一。 这意味着,例如,正则表达式中的“\N”(每个字符,但新的-
line) 适用于平台字符集。
从 v5.22 开始,当切换到重新定义的语言环境时,Perl 默认会发出警告
将任何 ASCII 可打印字符(加上“\t”和“\n”)转换为与预期不同的类。
这很可能仅在 EBCDIC 平台上的现代语言环境中发生,例如,
CCSID 0037 机器上的 CCSID 1047 语言环境移动“[”,但它可能发生在 ASCII 平台上
ISO 646 和其他基本上已经过时的 7 位语言环境。 事情可能还是
工作,取决于程序使用的 Perl 的哪些特性。 例如,在
上面的例子,其中“|” 变成“\w”,并且没有正则表达式在哪里
这很重要,程序可能仍然正常工作。 警告列出了所有字符
它可以确定可能会受到不利影响。
请注意: 损坏或恶意的“LC_CTYPE”语言环境定义可能导致明显不合格
被您的应用程序视为字母数字的字符。 对于严格匹配
(普通的)ASCII 字母和数字——例如,在命令字符串中——区域设置感知
应用程序应该使用带有“/a”正则表达式修饰符的“\w”。 参见“安全”。
分类 “LC_NUMERIC”: 数字 格式化
在适当的“POSIX::setlocale()”调用之后,并且在“use locale”形式的范围内
包括数字,Perl 遵守“LC_NUMERIC”语言环境信息,它控制
应用程序关于如何格式化数字以便于人类可读的想法。 多数情况
实现的唯一效果是更改用于小数的字符
点——也许来自“。” 到 ”,”。 这些函数不知道成千上万的细节
分离等等。 (如果您关心这些事情,请参阅“localeconv 函数”。)
使用 POSIX qw(strtod setlocale LC_NUMERIC);
使用语言环境;
setlocale LC_NUMERIC,“”;
$n = 5/2; # 将数字 2.5 分配给 $n
$a = " $n"; # 与语言环境相关的字符串转换
打印 "半个五是 $n\n"; # 语言环境相关的输出
printf "半个五是 %g\n", $n; # 语言环境相关的输出
打印“小数点是逗号\n”
如果 $n == (strtod("2,5"))[0]; # 语言环境相关的转换
另请参阅 I18N::Langinfo 和“RADIXCHAR”。
分类 “LC_MONETARY”: 格式化 of 货币 量
C 标准定义了“LC_MONETARY”类别,但不是受
其内容。 (具有标准委员会经验的人会认识到,
工作组决定搁置这个问题。)因此,Perl 基本上不接受
通知它。 如果你真的想使用“LC_MONETARY”,你可以查询它的内容——见
“localeconv 函数”——并使用它在您的应用程序中返回的信息
自己的货币金额格式。 但是,您可能会发现这些信息,
尽管它可能是庞大而复杂的,但仍然不能完全满足您的要求:
货币格式是一个难以破解的难题。
另请参阅 I18N::Langinfo 和“CRNCYSTR”。
“LC_TIME”
由“POSIX::strftime()”生成的输出,它构建了一个格式化的人类可读的日期/时间
字符串,受当前“LC_TIME”语言环境的影响。 因此,在法语语言环境中,输出
由 %B 格式元素(完整月份名称)为一年的第一个月生成
成为“詹维尔”。 以下是在当前语言环境中获取长月份名称列表的方法:
使用 POSIX qw(strftime);
对于 (0..11) {
$long_month_name[$_] =
strftime("%B", 0, 0, 0, 1, $_, 96);
}
注意:在这个例子中不需要“使用语言环境”:“strftime()”是一个 POSIX 函数,它
使用标准系统提供的“libc”函数,该函数始终遵守当前的“LC_TIME”
地方。
另见 I18N::Langinfo 和 "ABDAY_1".."ABDAY_7", "DAY_1".."DAY_7", "ABMON_1".."ABMON_12",
和“ABMON_1”...“ABMON_12”。
其他 类别
Perl 本身当前不使用其余的语言环境类别。 但再次注意
Perl 与之交互的事物可能会使用这些,包括标准之外的扩展
Perl 分发,并由操作系统及其实用程序。 特别注意的是
$! 的字符串值并且外部实用程序给出的错误消息可能会更改
通过“LC_MESSAGES”。 如果您想拥有可移植的错误代码,请使用“%!”。 见厄尔诺。
保安
虽然在 perlsec 中可以找到对 Perl 安全问题的主要讨论,但一个讨论
如果 Perl 的语言环境处理没有引起您对语言环境的注意,则它是不完整的——
依赖的安全问题。 区域设置——尤其是在允许非特权用户的系统上
建立自己的语言环境——是不可信的。 恶意(或只是简单损坏)的语言环境
可以使支持区域设置的应用程序产生意想不到的结果。 这里有一些
可能性:
· 使用“\w”正则表达式检查安全文件名或邮件地址可能是
被“LC_CTYPE”语言环境欺骗,声称诸如“>”和“|”之类的字符是
字母数字。
· 带有大小写映射的字符串插值,例如,“$dest = "C:\U$name.$ext"”,可能
如果伪造的“LC_CTYPE”案例映射表有效,则会产生危险的结果。
· 偷偷摸摸的“LC_COLLATE”语言环境可能会导致学生姓名为“D”级
出现在那些有“A”的人之前。
· 麻烦使用“LC_MONETARY”中的信息的应用程序可能会格式化
借方就好像它们是贷方一样,反之亦然,如果该语言环境已被颠覆。 或者
它可能会以美元而非港币付款。
· 由“strftime()”格式化的日期中的日期和日期名称可以被操纵为
能够破坏“LC_DATE”语言环境的恶意用户的优势。 (“看——它说我
周日不在大楼里。”)
此类危险并非区域设置系统所特有:应用程序的任何方面
可能被恶意修改的环境提出了类似的挑战。 相似地,
它们并非特定于 Perl:任何允许您编写程序的编程语言
考虑到他们的环境会使您面临这些问题。
Perl 不能保护您免受示例中显示的所有可能性的影响——没有
代替你自己的警惕——但是,当“使用区域设置”生效时,Perl 使用
污染机制(参见 perlsec)来标记变得依赖于语言环境的字符串结果,以及
结果可能是不可信的。 下面是对 tainting 行为的总结
可能受语言环境影响的运算符和函数:
· 竞品对比 运营商 (“lt”、“le”、“ge”、“gt”和“cmp”):
标量真/假(或小于/等于/大于)结果永远不会被污染。
· 案例映射 插值 (使用“\l”、“\L”、“\u”、“\U”或“\F”)
如果“使用区域设置”形式,则包含插值材料的结果字符串会受到污染
包括“LC_CTYPE”的有效。
· 匹配 操作者 (“米//”):
标量真/假结果永远不会被污染。
所有子模式,要么作为列表上下文结果交付,要么作为 $1 等。., 被污染了
如果包含“LC_CTYPE”的“使用语言环境”表单有效,并且子模式
正则表达式包含依赖于语言环境的构造。 这些构造包括
“\w”(匹配字母数字字符)、“\W”(非字母数字字符)、“\b”和
“\B”(词边界和非边界,取决于“\w”和“\W”匹配的内容),“\s”
(空白字符)、“\S”(非空白字符)、“\d”和“\D”(数字和
非数字)和 POSIX 字符类,例如“[:alpha:]”(参见“POSIX
字符类”在 perlrecharclass 中)。
如果模式不区分大小写(通过“/i”)匹配,也可能造成污染。
例外情况是,如果要以这种方式匹配的所有代码点都高于 255 并且执行
在 Unicode 规则下没有折叠到 256 以下。对这些没有进行污染
因为 Perl 只对这些代码点使用 Unicode 规则,而这些规则是
无论当前的语言环境如何,都一样。
匹配模式变量 $&、“$`”(匹配前)、“$'”(匹配后)和 $+(最后
匹配)也被污染。
· 换人 操作者 (“s//”):
具有与匹配运算符相同的行为。 此外,“=~”的左操作数变为
当包含“LC_CTYPE”的“使用区域设置”表单生效时被污染,如果修改为
基于正则表达式匹配的替换结果,涉及任何
上一项中提到的内容,或大小写映射的内容,例如“\l”、“\L”、“\u”,
"\U" 或 "\F"。
· 输出 格式 功能 (“printf()”和“write()”):
结果永远不会被污染,因为否则甚至打印输出,例如
如果“使用语言环境”有效,“print(1/7)”应该被污染。
· 案例映射 功能 ("lc()", "lcfirst()", "uc()", "ucfirst()"):
如果包含“LC_CTYPE”的“使用区域设置”表单有效,则结果会受到污染。
· POSIX 区域依赖 功能 ("localeconv()", "strcoll()", "strftime()",
“strxfrm()”):
结果永远不会被污染。
· POSIX 字符 程 测试 ("POSIX::isalnum()", "POSIX::isalpha()",
"POSIX::isdigit()", "POSIX::isgraph()", "POSIX::islower()", "POSIX::isprint()",
"POSIX::ispunct()", "POSIX::isspace()", "POSIX::isupper()", "POSIX::isxdigit()"):
真/假结果永远不会被污染。
三个示例说明了区域设置相关的污染。 第一个程序,它忽略了它的
语言环境,不会运行:直接从命令行获取的值不能用于命名
启用污点检查时的输出文件。
#/usr/local/bin/perl -T
# 使用污点检查运行
# 命令行完整性检查省略...
$tainted_output_file = 班次;
打开(F, ">$tainted_output_file")
或警告“打开 $tainted_output_file 失败:$!\n”;
该程序可以通过定期“清洗”受污染的值来运行
表达式:第二个示例——仍然忽略区域设置信息——运行,创建
如果可以,在其命令行上命名的文件。
#/usr/local/bin/perl -T
$tainted_output_file = 班次;
$tainted_output_file =~ m%[\w/]+%;
$untainted_output_file = $&;
open(F, ">$untainted_output_file")
或警告“打开 $untainted_output_file 失败:$!\n”;
将其与类似但可识别区域设置的程序进行比较:
#/usr/local/bin/perl -T
$tainted_output_file = 班次;
使用语言环境;
$tainted_output_file =~ m%[\w/]+%;
$localized_output_file = $&;
打开(F, ">$localized_output_file")
或警告“打开 $localized_output_file 失败:$!\n”;
第三个程序无法运行,因为 $& 被污染:它是匹配的结果
涉及“\w”,而“使用语言环境”有效。
环境
PERL_SKIP_LOCALE_INIT
这个环境变量,从 Perl v5.20 开始可用,如果设置(到任何
value),告诉 Perl 不要使用其余的环境变量
初始化为。 相反,Perl 使用当前的语言环境设置。
这在嵌入式环境中特别有用,请参阅“使用嵌入式 Perl
使用 POSIX 语言环境”在 perlembed 中。
PERL_BADLANG
一个可以抑制 Perl 关于失败区域设置的警告的字符串
启动。 如果操作系统中的语言环境支持是
以某种方式缺少(损坏)——或者如果您在
设置您的环境。 如果此环境变量不存在,或有
除了 "0" 或 "" 之外的值,Perl 会抱怨语言环境设置失败。
注意: "PERL_BADLANG" 只给你一种隐藏警告信息的方法。 这
消息告诉您系统的区域设置支持中的一些问题,并且您
应该调查问题是什么。
DPKG_RUNNING_VERSION
在 Debian 系统上,如果设置了 DPKG_RUNNING_VERSION 环境变量(到
任何值),区域设置失败警告将被抑制,就像
零 PERL_BADLANG 设置。 这样做是为了避免大量虚假警告
在系统升级过程中。 看http://bugs.debian.org/508764>.
以下环境变量不是 Perl 特有的:它们是
标准化(ISO C、XPG4、POSIX 1.c)“setlocale()”方法,用于控制
应用程序对数据的意见。 Windows 是非 POSIX,但 Perl 安排了以下内容
无论如何都要按照描述工作。 如果环境变量给出的区域设置无效,
Perl 会尝试优先级较低的下一个。 如果没有一个是有效的,在 Windows 上,系统
然后尝试默认语言环境。 如果所有其他方法都失败,则使用“C”语言环境。 如果即使那样
不起作用,有些东西严重损坏,但 Perl 试图继续前进
区域设置可能是。
"LC_ALL" "LC_ALL" 是 "override-all" 语言环境变量。 如果设置,它
覆盖所有其余的语言环境环境变量。
“语” 注意: "LANGUAGE" 是一个 GNU 扩展,它只在你使用
GNU库。 如果您使用的是 Linux,就会出现这种情况。 如果您正在使用
您最有可能是“商业”Unix 而不去 使用 GNU libc,你可以
忽略“语言”。
但是,如果您使用的是“LANGUAGE”:它会影响
命令输出的信息、警告和错误消息(换句话说,
它就像“LC_MESSAGES”)但它比“LC_ALL”具有更高的优先级。 而且,
它不是一个单一的值,而是一个“路径”(“:”分隔的列表) 语言
(不是语言环境)。 有关更多信息,请参阅 GNU“gettext”库文档
信息。
“LC_CTYPE” 在没有“LC_ALL”的情况下,“LC_CTYPE”选择字符类型区域设置。 在
“LC_ALL”和“LC_CTYPE”都没有,“LANG”选择字符类型
地方。
“LC_COLLATE”
在没有“LC_ALL”的情况下,“LC_COLLATE”选择整理(排序)
语言环境。 在“LC_ALL”和“LC_COLLATE”都不存在的情况下,“LANG”选择
校对语言环境。
“LC_MONETARY”
在没有“LC_ALL”的情况下,“LC_MONETARY”选择货币格式
语言环境。 在“LC_ALL”和“LC_MONETARY”都不存在的情况下,“LANG”选择
货币格式区域设置。
“LC_NUMERIC”
在没有“LC_ALL”的情况下,“LC_NUMERIC”选择数字格式区域设置。
在“LC_ALL”和“LC_NUMERIC”都没有的情况下,“LANG”选择数字
格式。
“LC_TIME” 在没有“LC_ALL”的情况下,“LC_TIME”选择日期和时间格式
语言环境。 在“LC_ALL”和“LC_TIME”都不存在的情况下,“LANG”选择
日期和时间格式化区域设置。
"LANG" "LANG" 是“包罗万象”的语言环境环境变量。 如果设置了,就是
用作整体“LC_ALL”和特定类别之后的最后手段
“LC_富”.
例子
“LC_NUMERIC”控制数字输出:
使用语言环境;
使用 POSIX qw(locale_h); # 导入 setlocale() 和 LC_ 常量。
setlocale(LC_NUMERIC, "fr_FR") 或死“原谅”;
printf "%g\n", 1.23; # 如果 "fr_FR" 成功,可能会显示 1,23。
以及“POSIX::strtod()”如何将字符串解析为数字:
使用语言环境;
使用 POSIX qw(locale_h strtod);
setlocale(LC_NUMERIC, "de_DE") 或 die "Entschuldigung";
我的 $x = strtod("2,34") + 5;
打印 $x, "\n"; # 可能显示 7,34。
附注
串 “评估” 和 “LC_NUMERIC”
字符串 eval 将其表达式解析为标准 Perl。 因此,它期待着
小数点为点。 如果“LC_NUMERIC”设置为逗号,则
解析会很困惑,也许是默默的。
使用语言环境;
使用 POSIX qw(locale_h);
setlocale(LC_NUMERIC, "fr_FR") 或死“原谅”;
我的 $a = 1.2;
打印 eval "$a + 1.5";
打印“\n”;
打印“13,5”。 这是因为在该语言环境中,逗号是小数点字符。
“eval”因此扩展为:
评估“1,2 + 1.5”
结果可能不是您所期望的。 不会产生警告。 如果你这样做
字符串“eval”在“use locale”范围内,您应该改为更改“eval”
行做类似的事情:
打印 eval "无语言环境;$a + 1.5";
这将打印 2.7。
你也可以排除“LC_NUMERIC”,如果你不需要它,通过
使用区域设置 ':!numeric';
落后 兼容性
5.004 之前的 Perl 版本 大多 忽略语言环境信息,通常表现为
如果类似于“C”语言环境的东西总是有效,即使程序
环境另有建议(请参阅“setlocale 函数”)。 默认情况下,Perl 仍然
这样做是为了向后兼容。 如果您希望 Perl 应用程序付费
注意区域设置信息,您 必须 使用“use locale”编译指示(请参阅“使用
locale" pragma") 或者,在不太可能的情况下,您只想为模式这样做
匹配,“/l”正则表达式修饰符(参见 perlre 中的“字符集修饰符”)
指示它这样做。
从 5.002 到 5.003 的 Perl 版本确实使用了“LC_CTYPE”信息(如果可用); 那
是,“\w”确实根据语言环境理解了字母是什么
变量。 问题是用户无法控制该功能:如果 C
库支持的语言环境,Perl 使用了它们。
I18N:整理 过时的
在 5.004 之前的 Perl 版本中,可以使用
“I18N::Collate”库模块。 这个模块现在有点过时了,应该避免
在新应用中。 “LC_COLLATE”功能现已集成到 Perl 核心中
语言:可以通过“使用语言环境”完全正常地使用特定于语言环境的标量数据,
因此不再需要处理“I18N::Collate”的标量引用。
排序 速度 和 记忆 使用 影响
按语言环境比较和排序通常比默认排序慢; 减速
已经观察了两到四次。 它也会消耗更多的内存:一次 Perl
标量变量参与了任何遵守规则的字符串比较或排序操作
locale 排序规则,它将比以前多 3-15 倍的内存。 (最正确
乘数取决于字符串的内容、操作系统和语言环境。)这些
缺点更多是由操作系统的语言环境系统实现决定的
比 Perl。
自如 可使用 当地 定义
Unicode CLDR 项目提取了其许多语言环境的 POSIX 部分,可在
http://unicode.org/Public/cldr/latest/
有大量的语言环境定义集合:
http://std.dkuug.dk/i18n/WG15-collection/locales/
您应该知道它不受支持,并且不声称适用于任何目的。
如果您的系统允许安装任意区域设置,您可能会找到定义
它们本身很有用,或者作为开发您自己的语言环境的基础。
18n 和 l10n
“国际化”通常缩写为 i18n 因为它的第一个和最后一个字母是
被其他十八个人隔开。 (你可能会猜到为什么 internalin ... internaliti ... i18n
倾向于缩写。)同样,“本地化”通常缩写为 l10n.
An 不完善
C 和 POSIX 标准中定义的国际化可以被批评为
不完整,笨拙,并且粒度太大。 (语言环境适用于整个
进程,当将它们应用于单个线程可能会更有用时,
窗口组,或者其他什么。)他们也有像标准组一样分裂的倾向
世界分为国家,当我们都知道世界同样可以分为
银行家、自行车手、游戏玩家等等。
统一 和 UTF-8
从 Perl v5.6 开始,对 Unicode 的支持是新的,并且实现的更加全面
在 v5.8 及更高版本中。 见 perluniintro。
从 Perl v5.20 开始,Perl 支持 UTF-8 语言环境,除了“LC_COLLATE”(使用
Unicode::Collate 代替)。 如果你有 Perl v5.16 或 v5.18 并且无法升级,你可以使用
使用语言环境 ':not_characters';
使用这种形式的 pragma 时,仅使用语言环境的非字符部分
通过 Perl,例如“LC_NUMERIC”。 Perl 假设你已经翻译了所有的
将要操作的字符转换为 Unicode(实际上是平台的本机字符集
(ASCII 或 EBCDIC)加 Unicode)。 对于文件中的数据,这也可以方便地完成
指定
使用 open ':locale';
此 pragma 安排将来自文件的所有输入从
环境中指定的当前语言环境(请参阅“环境”),以及所有输出到
要翻译回语言环境的文件。 (见打开)。 在每个文件句柄的基础上,您
可以改用 PerlIO::locale 模块或 Encode::Locale 模块,两者都可用
来自 CPAN。 后一个模块还具有简化“ARGV”处理的方法和
环境变量,可用于单个字符串。 如果你知道你所有的
语言环境将是 UTF-8,因为现在很多,您可以使用 -C 命令行开关。
这种形式的 pragma 允许使用 Unicode 无缝处理语言环境。 这
整理顺序将按 Unicode 代码点顺序排列。 强烈建议当
您需要对使用标准模块 Unicode::Collate 的字符串进行排序和排序
在许多情况下提供比旧式语言环境更好的结果
处理。
刚刚描述的所有模块和开关都可以在 v5.20 中使用,只需简单的“使用
区域设置”,并且,如果输入区域设置不是 UTF-8,您将得到不太理想的结果
使用 v5.16 之前的 Perls 或使用语言环境时获得的行为,如下所述
v5.16 和 v5.18 中没有 ":not_characters" 参数的编译指示。 如果您正在使用
v8 及更高版本中的 UTF-5.20 区域设置,本节的其余部分不适用于
你。
有两种情况,多字节和单字节语言环境。 第一个多字节:
Perl 可能支持的唯一多字节(或宽字符)语言环境是
UTF-8。 这是由于实现的困难,事实上高质量的 UTF-8
现在已为世界上的每个地区发布了语言环境
(<http://unicode.org/Public/cldr/latest/>),并且失败了所有你可以使用的
编码模块以翻译到/从您的语言环境。 所以,你必须做这些事情之一
如果您使用这些语言环境之一,例如 Big5 或 Shift JIS。 对于 UTF-8 语言环境,在
Perls(v5.20 之前)没有完整的 UTF-8 语言环境支持,它们可能工作得相当好
(取决于您的 C 库实现)仅仅因为它们和 Perl 都存储
以相同方式占用多个字节的字符。 然而,一些,如果不是大多数,C
库实现可能无法处理 Latin-1 上半部分的字符
范围 (128 - 255) 正确地位于“LC_CTYPE”之下。 查看字符是否为特定类型
在语言环境下,Perl 使用诸如“isalnum()”之类的函数。 您的 C 库可能不适用于
具有这些功能的 UTF-8 语言环境,而不是仅在较新的宽库下工作
像“iswalnum()”这样的函数,Perl 不使用。 这些多字节语言环境是
将其视为单字节语言环境,并将具有下述限制。
从 Perl v5.22 开始,当 Perl 检测到多字节语言环境时会发出警告消息
它不完全支持。
对于单字节语言环境,Perl 通常采用在代码点上使用语言环境规则的方法
可以放入单个字节,Unicode 规则适用于不能放入的那些(尽管这不是
统一应用,请参阅本节末尾的注释)。 这可以防止很多问题
在非 UTF-8 的语言环境中。 假设语言环境是 ISO8859-7,希腊语。 字符在
0xD7 有一个大写的Chi。 但是在 ISO8859-1 语言环境中,Latin1,它是一个乘法
标志。 POSIX 正则表达式字符类“[[:alpha:]]”将神奇地匹配
0xD7 在希腊语环境中但不是在拉丁语环境中。
但是,有些地方会出现这种情况。 某些 Perl 结构用于 Unicode
仅,例如“\p{Alpha}”。 他们假设 0xD7 始终具有其 Unicode 含义(或
在 EBCDIC 平台上等效)。 由于 Latin1 是 Unicode 的子集,而 0xD7 是
Latin1 和 Unicode 中的乘号,“\p{Alpha}”永远不会匹配它,
不分地域。 "\N{...}" 也会出现类似的问题。 在 v5.20 之前,它是
因此在普通的“使用语言环境”下使用“\p{}”或“\N{}”是个坏主意——除非 您可以
保证区域设置为 ISO8859-1。 请改用 POSIX 字符类。
这种方法的另一个问题是跨单字节/多字节的操作
字节边界没有明确定义,因此是不允许的。 (此边界介于
代码点在 255/256。)例如,小写拉丁大写字母 Y WITH DIAERESIS
(U+0178) 应该返回带分音符的拉丁文小写字母 Y (U+00FF)。 但在希腊
语言环境,例如,0xFF 处没有字符,Perl 无法知道是什么
0xFF 处的字符确实应该代表。 因此它不允许操作。
在这种模式下,U+0178 的小写字母是它自己。
如果您启用标准文件的自动 UTF-8 化,也会出现同样的问题
句柄、默认“open()”层和非 ISO8859-1、非 UTF-8 语言环境中的 @ARGV(通过使用
无论是 -C 命令行开关或“PERL_UNICODE”环境变量; 看
运行)。 事物被读取为 UTF-8,这通常意味着 Unicode
解释,但语言环境的存在导致它们在该语言环境中被解释
反而。 例如,Unicode 输入中的 0xD7 代码点,这应该表示
乘法符号,在希腊语语言环境下不会被 Perl 以这种方式解释。 这个
是没有问题的 提供 您确保所有语言环境始终且仅是
ISO8859-1,或者,如果您的 C 库没有缺陷,则使用 UTF-8 语言环境。
还有一个问题是这种方法可能导致两个代码点含义相同
特点。 因此,在希腊语环境中,U+03A7 和 U+00D7 都是希腊大写字母 CHI。
由于所有这些问题,从 v5.22 开始,Perl 将在多个
当单字节语言环境有效时,使用字节(因此是 Unicode)代码点。 (虽然
如果这样做会不合理地减慢执行速度,它不会检查这一点。)
供应商语言环境是出了名的错误,并且 Perl 很难测试它的语言环境——
处理代码,因为这与 Perl 无法控制的代码交互; 所以
Perl 中的语言环境处理代码也可能有问题。 (但是,Unicode 提供的
语言环境应该更好,并且有一个反馈机制可以纠正任何问题。 看
“免费提供的语言环境定义”。)
如果你有 Perl v5.16,如果你使用
“:not_characters”参数到语言环境编译指示(除了非
字符部分)。 如果您没有 v5.16,并且您 do 有可用的语言环境,使用
它们对于某些特定目的可能是值得的,只要您牢记
已经提到的问题。 例如,如果您的语言环境的排序规则有效,它将运行
在语言环境下比在 Unicode::Collate 下更快; 你可以访问诸如
当地货币符号以及月份和星期几的名称。 (但为了
重点强调一下,在 v5.16 中,您可以通过以下方式获得此访问权限,而没有语言环境的缺点
使用编译指示的“:not_characters”形式。)
注意:对于可以容纳在一个字节中的代码点使用区域设置规则的策略,以及 Unicode
那些不能的规则没有统一适用。 v5.12 之前的版本,有点
偶然; 在 v5.12 中,它相当一致地应用于正则表达式匹配
除了括号中的字符类; 在 v5.14 中,它扩展到所有正则表达式匹配; 和
在 v5.16 中的大小写操作,例如“\L”和“uc()”。 对于整理,在所有版本中
到目前为止,系统的“strxfrm()”函数被调用,无论它做什么,你都会得到什么。
使用 onworks.net 服务在线使用 perllocale