perl - 如何让 Perl 检测错误的 UTF-8 序列?

标签 perl unicode utf-8

我正在运行 Perl 5.10.0 和 Postgres 8.4.3,并将字符串输入到数据库中,该数据库位于 DBIx::Class 后面。 .

这些字符串应该是 UTF-8,因此我的数据库是以 UTF-8 运行的。不幸的是,其中一些字符串很糟糕,包含格式错误的 UTF-8,所以当我运行它时,我遇到了异常
DBI Exception: DBD::Pg::st execute failed: ERROR: invalid byte sequence for encoding "UTF8": 0xb5
我认为我可以简单地忽略无效的,然后担心格式错误的 UTF-8,因此使用此代码,它应该标记并忽略错误的标题。

if(not utf8::valid($title)){
   $title="Invalid UTF-8";
}
$data->title($title);
$data->update();

然而 Perl 似乎认为字符串是有效的,但它仍然抛出异常。

如何让 Perl 检测到错误的 UTF-8?

最佳答案

首先,请遵循文档 - utf8模块应该 仅限 用在'use utf8;'表格以表明您的源代码是 UTF-8 而不是 Latin-1。不要使用任何 utf8 函数。

Perl 区分字节和 UTF-8 字符串。在字节模式下,Perl 不知道也不关心您使用的是什么编码,如果您打印它,它将使用 Latin-1。以欧元符号 (€) 为例。在 UTF-8 中,这是 3 个字节,0xE2、0x82、0xAC。如果打印这些字节的长度,Perl 将返回 3。同样,它不关心编码。它可以是任何字节或任何编码,合法或非法。

如果您使用 Encode模块并调用Encode::decode("UTF-8', $bytes)你会得到一个新的字符串,它设置了所谓的 UTF8 标志。 Perl 现在知道你的字符串是 UTF-8 格式,并且会返回长度 1。
utf8::valid的问题仅适用于第二种类型的字符串。您的字符串可能是第一种形式,字节模式和 utf8::valid只为字节形式的任何东西返回 true。这记录在 perldoc 中。

解决方案是让 Perl 将您的字节字符串解码为 UTF-8,并检测任何错误。这可以通过 FB_CROAK 来完成,正如 brian d foy 解释的那样:

my $ustring =
    eval { decode( 'UTF-8', $byte_string, FB_CROAK ) }
    or die "Could not decode string: $@";

然后,您可以捕获该错误并跳过那些无效字符串。

或者,如果您知道您的代码主要是 UTF-8,并且到处都有一些无效序列,您可以使用:
my $ustring = decode( 'UTF-8', $byte_string );

它使用默认模式 FB_DEFAULT ,用 U+FFFD 替换无效字符,Unicode 替换字符(带问号的菱形)。

在大多数情况下,您可以将字符串直接传递给您的数据库驱动程序。某些驱动程序可能要求您首先将字符串重新编码回字节形式:
my $byte_string = encode('UTF-8', $ustring);

还有一些在线正则表达式,您可以在调用 decode 之前使用它们来检查有效的 UTF-8 序列。 (检查其他堆栈溢出答案)。如果您使用这些正则表达式,则无需进行任何编码或解码。

最后请使用UTF-8而不是 utf8在您调用 decode .后者更加宽松,允许一些无效的 UTF-8 序列(例如 Unicode 范围之外的序列)通过。

关于perl - 如何让 Perl 检测错误的 UTF-8 序列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2656401/

相关文章:

perl - 如何使用 perl 拼接引用数组?

perl - LWP::UserAgent 的 sslv3 警报握手失败

xml - 输入 XML 数据与输出 XML 格式不匹配

python - 为什么在 Django 模型中需要这个方法?

utf-8 - UTF8 感知 printf?

perl - 是否有一种优雅的方式来存储本体图和与节点关联的定义/数据?

c# - WebClient html 中的汉字与网站中的实际汉字不同

java - 如何使用 Unicode 或 Java 中的任何替代方法显示 "sigma-hat"? (我有部分解决方案)

iphone - 摄氏度符号问题 - Objective-C

c++ - 解析以 UTF-8 编码的 XML