Ada*_*son 20 perl sanitization utf-8
我的Perl程序从磁盘文件中获取一些文本作为输入,将其包装在某些XML中,然后将其输出到STDOUT.输入名义上是UTF-8,但有时会插入垃圾.我需要清理输出,以便不会发出无效的UTF-8八位字节,否则下游消费者(Sphinx)会爆炸.
至少,我想知道,如果数据是无效的,所以我能避免将它传递出去; 理想情况下,我只能删除有问题的字节.然而,启用我能找到的所有宿命论并不能让我在那里使用perl 5.12(FWIW,use v5.12; use warnings qw( FATAL utf8 );已生效).
我特别在顺序方面遇到麻烦"\xFE\xBF\xBE".如果我创建一个只包含这三个字节的文件(perl -e 'print "\xEF\xBF\xBE"' > bad.txt),尝试读取模式:encoding(UTF-8)错误的文件utf8 "\xFFFE" does not map to Unicode,但仅在5.14.0之下.5.12.3及更早版本是非常精细的阅读和后来写的序列.我不确定从哪里获得\xFFFE(非法反向BOM),但至少有一个投诉与Sphinx一致.
不幸的是,decode_utf8("\xEF\xBF\xBE", 1)在5.12或5.14下没有错误.我更喜欢不需要编码I/O层的检测方法,因为这只会给我留下错误信息并且无法清理原始八位字节.
我确信我需要解决更多的序列,但只是处理这个序列将是一个开始.所以我的问题是:在5.14之前用perl可以可靠地检测到这种问题数据吗?什么替代例程通常可以将几乎UTF-8清理成严格的UTF-8?
cjm*_*cjm 21
你应该阅读的UTF8与UTF8与UTF8部分中的 编码文档.
总而言之,Perl有两种不同的UTF-8编码.它的本机编码被调用utf8,并且基本上允许任何代码点,无论Unicode标准对该代码点的描述如何.
另一种编码称为utf-8(aka utf-8-strict).这仅允许按Unicode标准列为合法交换的代码点.
"\xEF\xBF\xBE",当解释为UTF-8时,解码为代码点U + FFFE.但根据Unicode,这对于交换来说是不合法的,因此对此类事情严格的程序会抱怨.
代替使用的decode_utf8(它使用不严utf8编码),可以使用decode与utf-8编码.阅读处理格式不正确的数据部分,了解处理或抱怨问题的不同方法.
更新:看起来有些版本的Perl不会抱怨U + FFFE,即使使用utf-8-strict编码也是如此.这似乎是一个错误.您可能只需构建Sphinx抱怨的代码点列表并手动过滤掉(例如tr).