使用Perl进行Unicode方式的清单

W3C*_*der 19 unicode perl utf-8

我正在帮助客户将他们的Perl平面文件公告板网站从ISO-8859-1转换为Unicode.

由于这是我第一次,我想知道以下"清单"是否完整.一切都在测试中很好用,但我可能会遗漏一些只会在极少数情况下发生的事情.

这是我到目前为止所做的事情(请原谅我只包括"摘要"代码示例):

  1. 确保文件始终以UTF-8读写:

    use open ':utf8';
    
    Run Code Online (Sandbox Code Playgroud)
  2. 确保收到CGI输入为UTF-8(该站点未使用CGI.pm):

    s{%([a-fA-F0-9]{2})}{ pack ("C", hex ($1)) }eg;    # Kept from existing code
    s{%u([0-9A-F]{4})}{ pack ('U*', hex ($1)) }eg;     # Added
    utf8::decode $_;
    
    Run Code Online (Sandbox Code Playgroud)
  3. 确保文本打印为UTF-8:

    binmode STDOUT, ':utf8';
    
    Run Code Online (Sandbox Code Playgroud)
  4. 确保浏览器将我的内容解释为UTF-8:

    Content-Type: text/html; charset=UTF-8
    <meta http-equiv="content-type" content="text/html;charset=UTF-8">
    
    Run Code Online (Sandbox Code Playgroud)
  5. 确保表单发送UTF-8(只要设置了页面编码,可能不需要):

    accept-charset="UTF-8"
    
    Run Code Online (Sandbox Code Playgroud)
  6. 不要认为我需要以下内容,因为内联文本(菜单,标题等)仅以ASCII格式显示:

    use utf8;
    
    Run Code Online (Sandbox Code Playgroud)

这看起来合理还是我错过了什么?

编辑:我可能还应该提到,我们将运行一次性批处理来读取所有现有的文本数据文件并将其保存为UTF-8编码.

dax*_*xim 26

  • :utf8 PerlIO不够严格.它允许输入满足UTF-8字节序列的结构要求,但为了良好的安全性,您希望拒绝实际上不是有效Unicode的内容.与无处不在更换它PerlIO::encoding层,即::encoding(UTF-8).

  • 出于同样的原因,总是Encode::decode('UTF-8', …),不是Encode::decode_utf8(…).

  • 通过异常使解码失败,比较:

    perl -E'use Encode qw(decode); say decode(q(UTF-8), qq(\x{c0})); say q(survived)'
    perl -E'use Encode qw(decode); say decode(q(UTF-8), qq(\x{c0}), Encode::FB_CROAK); say q(survived)'
    
    Run Code Online (Sandbox Code Playgroud)
  • 你没有在%u符号中照顾代理对.这是我在列表中看到的唯一主要错误.2.写得正确为:

    use Encode qw(decode);
    use URI::Escape::XS qw(decodeURIComponent);
    $_ = decode('UTF-8', decodeURIComponent($_), Encode::FB_CROAK);
    
    Run Code Online (Sandbox Code Playgroud)
  • 不要乱用utf8模块中的功能.它的文件说明了.它的目的是告诉Perl源代码是UTF-8.如果要进行编码/解码,请使用该Encode模块.

  • utf8无论如何在每个模块中添加pragma.它不会受到伤害,但是如果有人添加了这些字符串文字,您将面向未来的代码维护.另见CodeLayout::RequireUseUTF8.

  • 雇用encoding::warnings抽出剩余的隐式升级.验证每种情况是否有意/需要.如果是,请将其转换为显式升级Unicode::Semantics.如果没有,这是一个提示,你应该早些时候有一个解码步骤.来自http://p3rl.org/UNI的文档提供了在从源接收数据后立即解码的建议.去了其中的代码被读/写数据的地点,并验证你有一个解码/编码步骤中,明确地(decode('UTF-8', …))或隐式地通过层(use open编译,binmode,3参数的形式的open).

  • 为了调试:如果你不知道是在一个变量中,表示在一定的时间,你不能只是什么绳print,使用的工具Devel::StringInfoDevel::Peek替代.

  • 这些序列无效,但是一些用户代理可能将0xC0 0xB3视为"<",这可能导致跨站点脚本.现代桌面浏览器不; 它已在IE6SP1和Opera(我认为~8)中修复,但可能还有其他鲜为人知的浏览器仍然出错.因此,您应该过滤无效UTF-8序列的字符串.您可以同时删除其他不需要的控制字符. (3认同)

bri*_*foy 8

你总是想念一些东西.但问题通常是未知的未知数.:)

有效的Perl编程有一个Unicode章节,涵盖了许多Perl基础知识.我们没有介绍的一个项目是您必须做的一切,以确保您的数据库服务器和Web服务器做正确的事情.

您还需要做的其他事情:

  • 升级到最新的Perl即可.Unicode的东西在5.8中变得更容易,在5.10中更容易.

  • 确保将网站内容转换为UTF-8.您可以编写一个爬行程序来查找页面并查找Unicode替换字符(看起来像带有问号的菱形的东西).让我们看看我是否可以在StackOverflow中创建它:

  • 确保您的数据库服务器支持UTF-8,您已经设置了具有UTF-8感知列的表,并且您告诉DBI在其驱动程序中使用UTF-8支持(其中一些在本书中).

  • 确保查看@ARGV的任何内容都将项目从命令行的语言环境转换为UTF-8(它在书中).

如果您发现其他任何事情,请通过回答您自己的问题告诉我们.;)

  • 有关您的所有电子选项,请访问[www.effectiveperlprogramming.com](http://www.effectiveperlprogramming.com)网站.您可以获得PDF,电子书,Kindle,以及在Safari Books Online中阅读. (3认同)
  • 我不知道你是否可以在线购买.它出现在许多英语世界的主要书籍卖家,但我不知道你可以得到什么.我确实有一大堆我可以在世界上几乎(几乎)发送的东西. (2认同)