0

当我从 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).
4

2 回答 2

1

“打印中的宽字符”警告让我认为您的输出文件句柄不希望看到 utf-8 字符。

perldiag手册页更详细地解释了Perl 错误和警告。这是关于此警告的内容。

%s 中的宽字符

(S utf8) Perl 遇到了一个宽字符 (>255),但它没有预料到它。此警告默认为 I/O(如打印)打开。消除此警告的最简单方法是将 :utf8 层添加到输出中,例如 binmode STDOUT, ':utf8' 。另一种关闭警告的方法是添加 no warnings 'utf8'; 但这通常更接近作弊。通常,您应该使用编码显式标记文件句柄,请参阅 open 和 binmode。

我怀疑您也会从阅读Perl Unicode 教程(以及骆驼书第 4 版的第 6 章)中受益。

于 2012-07-24T10:46:55.487 回答
0

已移除

% use utf8;

来自其中一个模板,然后按应有的方式显示该文本。

于 2012-07-24T14:55:21.597 回答