【问题标题】:UTF8 strings partially not recognizedUTF8 字符串部分无法识别
【发布时间】:2012-07-24 09:32:38
【问题描述】:

当我从 SQLite3 数据库中获取 Cyrillic 文本时,在某些情况下 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}

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

更新:我能够追踪到这个问题的根源。看起来格式错误的字符串是从网页上的用户输入中获取的,并作为参数发送到控制器操作: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).

【问题讨论】:

标签: perl unicode mojolicious


【解决方案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 章)中受益。

【讨论】:

  • 我认为这无关紧要:这些警告是由 Log4perl 附加程序产生的。
  • 你可能是对的。但这表明您的系统中有 somewhere 的 utf-8 数据。试着告诉 appenders 期待 utf-8 数据,看看有什么变化。我的其他建议仍然适用。处理 utf-8 数据时可能会出错。阅读文档。
  • 我再次查看了我的模板,发现'% use utf8;'。删除它解决了这个问题。
【解决方案2】:

已删除

% use utf8;

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-01
    • 2016-07-25
    • 1970-01-01
    • 2013-02-17
    • 2018-05-10
    • 2019-02-18
    • 2020-12-18
    相关资源
    最近更新 更多