部分无法识别UTF8字符串

时间:2012-07-24 09:32:38

标签: perl unicode mojolicious

当我从SQLite3数据库中获取西里尔文本时,在某些情况下perl(或Mojolicious,或者DBIx :: Class - 我老实说不知道)无法解码字节流。例如,给出文字:

1984г1ф!!11четыре

输出将是:

1984г1ф!!11������
1984\x{433}1\x{444}!!11\x{fffd}\x{fffd}\x{fffd}\x{fffd}\x{fffd}\x{fffd}

为什么会这样?如何解决这个问题?

更新:我能够追踪此问题的来源。看起来格式错误的字符串来自网页上的用户输入,并作为参数调度到Controller操作:code here

执行保存操作会生成以下日志:

[2012/07/24 14:06:09] [DEBUG] 15703 Mojolicious.Plugin.RequestTimer - POST /admin/node/save (Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:14.0) Gecko/20100101 Firefox/14.0.1).
[2012/07/24 14:06:09] [DEBUG] 15703 Mojolicious.Routes - Routing to a callback.
[2012/07/24 14:06:09] [DEBUG] 15703 Mojolicious.Routes - Routing to controller "MyApp::Admin" and action "save".
Wide character in print at /home/nikita/perl5/lib/perl5/Log/Log4perl/Appender/File.pm line 245.
Wide character in print at /home/nikita/perl5/lib/perl5/Log/Log4perl/Appender/Screen.pm line 39.
[2012/07/24 14:06:09] [DEBUG] 15703 MyApp.Admin - 123123!!!11������������������

更新2:我使用Morbo作为开发服务器,我的应用程序布局包含meta标题:

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

更新3:奇怪,但有时字符串已编码并正确显示:

[2012/07/24 14:55:52] [DEBUG] 16451 Mojolicious.Routes - Routing to a callback.
[2012/07/24 14:55:52] [DEBUG] 16451 Mojolicious.Routes - Routing to controller "MyApp::Admin" and action "save".
[2012/07/24 14:55:52] [DEBUG] 16451 MyApp.Admin - 112!!ЫВафывафывп
[2012/07/24 14:55:52] [DEBUG] 16451 Mojolicious.Plugin.RequestTimer - 302 Found (0.326543s, 3.062/s).
[2012/07/24 14:55:52] [DEBUG] 16451 Mojolicious.Plugin.RequestTimer - GET /admin (Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:14.0) Gecko/20100101 Firefox/14.0.1).

如果我第二次做同样的事,我得到:

[2012/07/24 14:57:30] [DEBUG] 16451 Mojolicious.Routes - Routing to controller "MyApp::Admin" and action "save".
Wide character in print at /home/nikita/perl5/lib/perl5/Log/Log4perl/Appender/File.pm line 245.
Wide character in print at /home/nikita/perl5/lib/perl5/Log/Log4perl/Appender/Screen.pm line 39.
[2012/07/24 14:57:30] [DEBUG] 16451 MyApp.Admin - 112!!��������������������
[2012/07/24 14:57:30] [DEBUG] 16451 Mojolicious.Plugin.RequestTimer - 302 Found (0.362417s, 2.759/s).
[2012/07/24 14:57:30] [DEBUG] 16451 Mojolicious.Plugin.RequestTimer - GET /admin (Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:14.0) Gecko/20100101 Firefox/14.0.1).

2 个答案:

答案 0 :(得分:1)

“打印中的宽字符”警告让我觉得你的输出文件句柄不会期望看到utf-8字符。

perldiag手册页详细介绍了Perl错误和警告。以下是关于此警告的内容。

  

%s中的广角色

     

(S utf8)Perl在不期待的时候遇到了一个宽字符(> 255)   一。默认情况下,此警告用于I / O(如打印)。最简单的   安静此警告的方法只是将:utf8图层添加到   输出,例如binmode STDOUT,':utf8'。另一种关闭方式   警告是不添加警告'utf8';但那往往更接近   作弊。一般来说,你应该明确标记   带编码的文件句柄,请参阅open和binmode。

我怀疑你也会从阅读Perl Unicode Tutorial(以及4th edition of the Camel book的第6章)中受益。

答案 1 :(得分:0)

删除

% use utf8;

从其中一个模板中,然后显示该文本。