【问题标题】:How to Encode and Decode "Acute accented characters" using Perl如何使用 Perl 编码和解码“重音字符”
【发布时间】:2013-02-21 05:48:34
【问题描述】:

我在一个基于 Web 的教育网站工作,我们使用 Perl、MySQL 5、Apache 和 Template Toolkit。我们计划在我们的网站中引入对多语言的支持。

我们做了什么

如果我们的模板文件中有一个类似于 Courses Main Page 的选项卡名称,我们已将其转换为

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<h1>[% glossary.$language.courses_main_page %]<\h1> 

$language 获取用户登录时选择的值。

我们在 Mysql DB 中有一个表来维护这些数据:

创建表translation (english varchar(255) NOT NULL,
language varchar(255) NOT NULL, translation varchar(2000) NOT NULL, ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='翻译 元素文字转外语'

在 MySQL 的连接函数中,我提供了 'SET character_set_results=NULL'。 我尝试使用 utf8,但仅限于某些选项卡的问题增加了很多部分。

因此,一旦用户登录系统,我们就会获取所有翻译并将其存储在 PERL 哈希中并缓存它。我们将此哈希传递给模板文件,模板文件将替换该值。

问题:á 和 é 等重音符号正在被一些不同的字符集符号取代。

例如:在前端,我们看到 Cursos Página Principal 的“Cursos Página Principal”。

htmlentities and é (e acute)中给出的解决方案非常相似

谁能告诉我如何在 Perl 中实现同样的功能。

【问题讨论】:

    标签: html mysql perl template-toolkit


    【解决方案1】:

    表示字符集

    例如:在前端,我们看到 Cursos Página Principal 的“Cursos Página Principal”。

    当字符被传输为 UTF-8 但被解释为 ISO-8859-1 或类似时,会发生此mojibake。因此,我建议解决此问题的最简单方法是确保您的 HTML 页面以正确的 mime 类型发送到客户端,即

    Content-Type: text/html; charset=utf-8
    

    如果该信息存在于 HTML 标头中,则该值将覆盖 HTML 文档本身中的任何设置。因此,请确保您设置了 HTML 标头,或者您的 HTML 标头根本不指定字符集,以便浏览器查看元设置。

    在某些浏览器(例如 Firefox)中,您可以使用视图/字符编码手动更改字符集。您可以使用它来检查渲染时错误的字符编码是否真的是问题的原因。

    其实就是编解码

    在某些情况下修复字符集无济于事。可能是您根本无法控制框架的那一部分。或者某些东西将您的字符从 ISO-8859-1 转换为 UTF-8 两次,因此不可读的符号实际上已经表示为 UTF-8。在这些情况下,您可以使用Encode 模块直接对 Perl 中的字符进行编码,使用 HTML 字符引用作为输出:

    use Encode qw(decode encode FB_HTMLCREF);
    # maybe: $unicodeString = decode("utf-8", $byteString);
    $htmlString = encode("ascii", $unicodeString, FB_HTMLCREF);
    

    decode 步骤是否必要取决于您与数据库的通信方式。如果您的数据库连接能够支持 unicode,那么您已经有了 unicode 字符串,您可以简单地将它们编码为 HTML。对于DBD::mysql,有一个参数mysql_enable_utf8 =&gt; 1 可以实现这一点。使用它比在您自己的代码中解码内容更可取。 This answer 有语法细节。

    这些函数作用的一个例子:

    $byteString    = "Cursos P\xc3\xa1gina Principal.";   # two bytes
    $unicodeString = "Cursos P\N{U+00E1}gina Principal."; # one unicode character
    $htmlString    = "Cursos P&#225;gina Principal.";     # html character reference
    

    【讨论】:

    • 感谢您提供此信息。有效。我不需要解码步骤,因为 Db 正在处理它。我看到一些仍然无法阅读的地方。 “所有当前条款”应显示为“Todos los términos actuales”,但显示为“Todos los términos actuales”。我现在正在调试它。 charset=utf-8 不适合我。它重新引入了问题。
    • 从数据库中读取数据并将其标记为utf8可能有问题(例如通过:encoding(utf-8)层);我认为手动运行编码更好。
    • @JakubNarębski:我同意。这看起来像是有人在重新编码东西。这在输入可能包含必须为 HTML 编码的字符的情况下是有意义的。如果这仅影响某些文本,则表明文本沿不同的路径传递。消除这些差异可能有助于找到适合所有情况的解决方案:要么总是传递 HTML 字节,要么总是传递 unicode 字符串,要么总是传递 UTF-8 字节。
    • @user1254174:请注意上述 cmets。太糟糕了I couldn't notify both of you 在我之前的评论中。
    猜你喜欢
    • 2011-11-29
    • 1970-01-01
    • 1970-01-01
    • 2021-04-10
    • 2021-10-27
    • 2012-09-16
    • 2019-03-06
    相关资源
    最近更新 更多