如何在Perl CGI中实现万无一失的unicode处理?

时间:2015-01-09 00:06:30

标签: perl unicode

所以我有一个mysql数据库服务于我备份的旧wordpress db。我正在编写一些简单的perl脚本来提供wordpress文章(我不想安装wordpress)。

无论出于何种原因,WordPress都将所有引号存储为unicode字符,所有...作为unicode字符,所有双重破折号,所有撇号,所有地方都有unicode - 这是一团糟(这就是为什么我不这样做一个wordpress安装)。

在我的测试环境中,这是Linux Mint 17.1 Perl 5.18.2 Mysql 5.5,当我使用“charset = utf-8”提供内容类型的行时,大多数情况下工作正常(除了撇号只是从来没有正确解码)无论我尝试什么组合我都会尝试)。省略charset会导致所有unicode字符中断(除了撇号现在有效)。这是没关系的,除了撇号之外,我对正在发生的事情表示不满,并对数据进行了处理。

现在在我的生产环境中,这是一个VM,是Linux CentOS 6.5 Perl 5.10.1 Mysql 5.6.22,这里的东西根本不起作用。我是否在Content-type中包含“charset = utf-8”没有区别,没有unicode charatcers正常工作(包括撇号)。也许它与较低版本的Perl有关?有没有人有任何见解?

除了这个非常具体的案例外,有没有人知道用于处理来自数据库的unicode的万无一失的Perl习语? (我不确定管道中出现了什么问题,但我怀疑它是在DB驱动程序级别)

其中一个问题是我的数据非常不一致和脏。我可以解析整个数据库并清理所有unicode并重新导入它 - 关键是我要避免这种情况。我想要一个适合所有Perl脚本集合的单一尺寸用于阅读wordpress数据库。

1 个答案:

答案 0 :(得分:1)

处理Perl和UTF-8对我来说很痛苦。经过大量的时间,我了解到Perl中没有“万无一失的unicode处理”......但是有一个unicode处理可以提供帮助:

编码模块。

正如perlunifaq所说(http://perldoc.perl.org/perlunifaq.html):

  

我应该何时解码或编码?

     

每当您与外部的任何内容进行文本通信时   您的perl进程,如数据库,文本文件,套接字或其他   程序。即使你正在与之交流的东西也是写的   在Perl。

因此,我们对发送到Perl进程的每个UTF-8文本字符串执行此操作:

my $perl_str = decode('utf8',$myExt_str);

这是从Perl发送到Perl进程外部的任何文本字符串:

my $ext_str = encode('utf8',$perl_str);

...

当我们从/向mysql或postgresql数据库检索或发送数据时,现在有很多编码/解码。但不要害怕,因为有一种方法可以告诉Perl每个TEXT STRING来自/到数据库是utf8。另外,我们告诉数据库每个文本字符串都应该被视为UTF-8。唯一的缺点是你需要确保每个文本字符串都是UTF-8编码的...但这是另一个故事:

# For MySQL:
# This requires DBD::mysql version 4 or greater
use DBI;
my $dbh = DBI->connect ('dbi:mysql:test_db',
    $username,
    $password,
    {mysql_enable_utf8 => 1}
);

好的,现在我们在utf8中有来自数据库的文本字符串,数据库知道我们所有的文本字符串都应该被视为UTF-8 ......但是其他什么呢?我们需要告诉Perl(AND CGI)我们在进程中编写的每个文本字符串都是utf8并告诉其他进程将我们的文本字符串视为UTF-8:

use utf8;
use CGI '-utf8';

my $cgi = new CGI;
$cgi->charset('UTF-8');

已更新!

  

什么是“广角”?

     

这是一个术语,用于序数值更大的字符   127,序数值大于255的字符,或者任何字符   字符占用多个字节,具体取决于上下文。该   Perl警告“宽字符......”是由带有字符的字符引起的   序数值大于255。

     

没有指定的编码层,Perl   为了向后兼容的原因,我试图在ISO-8859-1中使用。   当它不能时,它会发出此警告(如果启用了警告),并且   改为输出UTF-8编码数据。避免这种警告并避免   在单个流中具有不同的输出编码,始终指定   显式编码,例如使用PerlIO层:

# The next line is required to avoid the "Wide character in print" warning
# AND to avoid having different output encodings in a single stream.
binmode STDOUT, ":encoding(UTF-8)";

...

即使有了这些,有时你需要编码('utf8',$ perl_str)。这就是为什么我知道在Perl中没有万无一失的unicode处理。请阅读perlunifaq(http://perldoc.perl.org/perlunifaq.html

我希望这会有所帮助。