如何在perl CGI param中使用unicode

时间:2013-12-06 12:57:05

标签: perl unicode utf-8 cgi

我有一个Perl CGI脚本接受unicode字符作为参数之一 网址的格式为

.../worker.pl?text="some_unicode_chars"&...

在perl脚本中,我将$ text变量传递给shell脚本:

system "a.sh \"$text\" out_put_file"; 

如果我在perl脚本中对文本进行硬编码,则效果很好。但是,当使用CGI从Web获取$ text时,输出没有意义。

my $q = CGI->new;  
my $text = $q->param('text'); 

我怀疑是编码引起了问题。 uft-8给我带来了很多麻烦。有人请帮帮我吗?

2 个答案:

答案 0 :(得分:3)

也许这会有所帮助。来自Perl Programming/Unicode UTF-8

  

默认情况下,CGI.pm不会解码您的表单参数。您可以使用   -utf8编译指示,它将所有参数视为(和解码)   UTF-8字符串,但如果您有任何二进制文件上传,这将失败   领域。更好的解决方案涉及覆盖param方法:   (示例如下)

[错误 - 请参阅更正] 此处为documentation for the utf-8 pragma。由于上传二进制数据似乎不是您的问题,因此使用utf-8编译指示似乎是最直接的方法。

更正:根据@Slaven的评论,不要将常规Perl utf8 pragma与已定义用于CGI.pm的{​​{3}}混淆:

  

-utf8

     

这使得CGI.pm将所有参数视为UTF-8字符串。使用它   小心,因为它会干扰二进制上传的处理。它   最好手动选择预期返回utf-8的字段   字符串并使用以下代码转换它们:

use Encode;
my $arg = decode utf8=>param('foo');

跟进: duleshi,你问:但我还是不明白Encode和utf8 :: decode之间的解码差异。 Encode和utf8模块有何不同?

来自-utf-8 pragma的文档:

  

请注意,此函数不处理任意编码。因此   建议将编码用于一般用途;另见utf8 pragma

换句话说,Encode模块可以使用 许多 不同的编码(包括UTF-8),而utf8函数可以工作<使用UTF-8编码强>

这是一个Perl程序,它演示了编码和解码UTF-8的两种方法的等价性。 (另请参阅Encode。)

#!/usr/bin/perl

use strict;
use warnings;
use utf8;  # allows 'ñ' to appear in the source code

use Encode;

my $word = "Español";  # the 'ñ' is permitted because of the 'use utf8' pragma

# Convert the string to its UTF-8 equivalent.
my $utf8_word = Encode::encode("UTF-8", $word);

# Use 'utf8::decode' to convert the string back to internal form.
my $word_again_via_utf8 = $utf8_word;
utf8::decode($word_again_via_utf8);  # converts in-place

# Use 'Encode::decode' to convert the string back to internal form.
my $word_again_via_Encode = Encode::decode("UTF-8", $utf8_word);

# Do the two conversion methods produce the same result?
# Prints 'Yes'.
print $word_again_via_utf8 eq $word_again_via_Encode ? "Yes\n" : "No\n";

# Do we get back the original internal string after converting both ways?
# Prints 'Yes'.
print $word eq $word_again_via_Encode ? "Yes\n" : "No\n";

答案 1 :(得分:1)

如果您在参数列表中传递UTF-8数据,那么您肯定希望使用URI::Escape模块对它们进行URI编码。这会将任何扩展字符转换为百分比值,这些值很容易打印和读取。在接收端,您需要在继续之前对其进行URI 解码