如何检测UTF字符格式不正确的问题

11

在使用SQL*Loader加载数据时,我希望使用Perl脚本检测和替换格式不正确的UTF-8字符,并将其替换为空格。我应该如何实现这个功能?

4个回答

3
考虑Python。它允许使用者扩展编解码器,以自定义的错误处理程序替换无法解码的字节为任何想要的内容。
import codecs
codecs.register_error('spacer', lambda ex: (u' ', ex.start + 1))
s = 'spam\xb0\xc0eggs\xd0bacon'.decode('utf8', 'spacer')
print s.encode('utf8')

这将打印:

spam  eggs bacon

1

编辑:(删除关于 SQL Loader 的部分,因为它似乎不再相关。)

一个问题将是确定什么算是畸形的 UTF-8 字符的“结尾”。很容易说什么是非法的,但下一个合法字符从哪里开始可能并不明显。


找到下一个字符的起始位置很容易 - 这是UTF-8设计中非常酷的事情之一。http://tools.ietf.org/html/rfc3629 - Mike G.
2
仅在格式良好的UTF-8中易于处理。想象一下插入重复引导字节-您必须跳过第一个出现的引导字节。如果您只是遵循UTF-8规则,则下一个字符似乎以重复引导字节的字符的最后一个字节开头。 - MSalters
@MSalters:这就是我所考虑的事情,但我对自己不够确定 :) - Jon Skeet

1

RFC 3629描述了UTF-8字符的结构。如果你看一下,你会发现找到无效字符非常简单,并且下一个字符边界总是很容易找到(它是一个字符<128,或者是“长字符”起始标记之一,前导位为110、1110或11110)。

但BKB可能是正确的——最简单的答案是让Perl为你做这件事,尽管我不确定当Perl在生效的过滤器中检测到不正确的UTF-8时会发生什么。


0
昨天,与平常的输出不同,我收到了一个定时任务的消息:
/etc/cron.daily/syslogrotate:
Malformed UTF-8 character (fatal) at /root/bin/maillogstats.pl line 55, <> line 12335.

日志文件中包含一行以类似 less -N 的方式呈现:

 12335 Apr 29 14:07:46 22 north courieresmtpd: error,relay=***.***.125.226,port=41522,msg="502 ESMTP command error",cmd: ....<A7>.

这个脚本从以下语句开始:

use utf8;
use open qw(:std :utf8);

我根据在Wikibooks中找到的建议进行了更改

use utf8;
use open qw(:std :encoding(UTF-8));

就是这样。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接