我有用Pl / Perl编写的存储过程:
CREATE FUNCTION strip_html_tags(text) RETURNS TEXT AS $$
use HTML::Strip;
my $hs = HTML::Strip->new();
my $clean_text = $hs->parse($_[0]);
$hs->eof;
return $clean_text;
$$ LANGUAGE plperlu;
我的数据库中有一些字段(LATIN1 encodend)可能有一些无效的字符,因为我得到的结果如下:
db=# select strip_html_tags(field) from table;
ERROR: character 0xe2809c of encoding "UTF8" has no equivalent in "LATIN1"
CONTEXT: PL/Perl function "strip_html_tags"
我尝试过使用PostgreSQL的convert()和convert_from()来尝试更改编码,但没有任何运气。有什么想法吗?
提前致谢。
答案 0 :(得分:1)
我想这里发生的事情是strip_html_tags
将HTML实体解码为原生Unicode代码点,表示为utf-8编码文本。 0xe2809c
被解码为utf-8字节序列the unicode code point U+201c LEFT DOUBLE QUOTATION MARK
- the character “
,这完全可以理解为您从HTML中的解码转义中获得的内容,尤其是由GUI编辑器或MS Word生成的HTML。它在HTML中表示为“
,“
(十进制)或“
(十六进制)。
由于您的数据库编码是latin-1,因此您无法在数据库中表示许多这些已解码的字符。
如果您要使用完整的unicode数据,您应该考虑将数据库更改为utf-8。如果您的数据库真的在latin-1
而不是(呃)SQL_ASCII
,这通常很难。只需转储数据库,使用ENCODING 'utf-8'
创建一个新数据库并将数据加载到其中以验证并检查它。针对转换后的数据库测试您的应用程序,并确保它们正确处理unicode文本。如果您满意,请停止您的应用,再次转储数据库,重新加载数据库,重命名旧数据库,然后将新数据库重命名为旧旧数据库的名称。
如果您愿意修改HTML,可以use Perl modules features to do a lossy encoding conversion from UTF-8 to Latin-1。 Perl模块可以执行诸如将“
替换为"
,将—
(使用短划线)替换为-
(减号)等等,并且可以删除非模块可替换的字符或用替换字符替换它们,如“?”。这是单向,有损转换;如果您没有保留原始未更改版本的副本,则无法获取原始数据。
您唯一的另一种选择是将数据作为bytea
- utf-8编码的字节字符串 - 然后将它们解码回应用程序中的文本。我真的不推荐这个。