我的Perl程序从磁盘文件中获取一些文本作为输入,将其封装在一些XML中,然后将其输出到STDOUT。输入名义上是UTF-8,但有时会插入垃圾。我需要对输出进行净化,这样就不会发出无效的UTF-8八位字节,否则下游消费者(Sphinx)就会崩溃。
至少我想知道是否数据无效,这样我就可以避免传递它;理想情况下,我可以只删除有问题的字节。然而,启用我能找到的所有宿命论并不能让我使用perl5.12(FWIW,<code>使用v5.12;使用警告qw(FATAL utf8)代码>生效)。
我特别在“xFExBFxBE”
序列上遇到问题。如果我创建了一个只包含这三个字节的文件(perl-eprint“xEFxBFxBE”>;bad.txt
),则尝试以:encoding(UTF-8)
模式读取文件时出错,并使用utf8“xFFFE”不会映射到Unicode
,而只能在5.14.0以下。5.12.3和更早的版本是非常好的阅读和以后写的序列。我不确定它是从哪里得到xFFFE
(非法反向BOM)的,但至少投诉与斯芬克斯一致。
不幸的是,decode_utf8(“xEFxBFxBE”,1)
不会导致5.12或5.14下的错误。我更喜欢一种不需要编码I/O层的检测方法,因为这只会给我留下一条错误消息,而且无法清除原始八位字节。
我确信还有更多的序列需要处理,但处理这一个序列将是一个开始。所以我的问题是:我能用5.14之前的perl可靠地检测这种问题数据吗?什么样的替换例程通常可以将almost-UTF-8净化为严格的UTF-8?