我在Perl中遇到土耳其语问题。我设置了土耳其语字符集,但我的土耳其字符显示不正确。
这是我的Perl脚本。
#!"c:\xampp\perl\bin\perl.exe"
use strict;
use warnings;
use CGI qw(:standard);
my $name = param('name');
my $surname = param('surname');
my $age = param('age');
my $gender = param('gender');
my $q = new CGI;
# We're outputting plain text, not HTML
print $q->header(-content_type => 'text/plain' , -charset => 'ISO-8859-9');
my $text = $name." ".$surname." ".$age." ".$gender." kaydı, sistemde yapılacak olan güncellemelerden sonra sisteme başarıyla eklenecektir.";
# printf("%s %s %d %d kaydı, sistemde yapılacak olan güncellemelerden sonra sisteme başarıyla eklenecektir.", $name , $surname , $age , $gender);
print $text;
我该如何解决这个问题?
答案 0 :(得分:3)
首先:不要在CGI.pm中使用HTML生成功能。使用它们会导致表达层无法维护。相反,使用基于Template Toolkit的模板来分隔演示文稿和功能。
其次,请勿使用indirect object notation。也就是说,不要写:
my $cgi = new CGI;
相反,写一下
my $cgi = CGI->new
使用$q
或$query
来引用CGI对象是很奇怪的,它源于WWW的早期阶段。当你从零开始学习时,没有理由使它永久化。
此外,假设您刚刚实例化了一个对象,请不要使用param
之类的普通子进程,也不要污染脚本的命名空间。使用以下方法访问参数值:
my $value = $cgi->param('surname');
最后,如果您要在源代码中使用“有趣”字符,例如Ş
,请将源代码保存为UTF-8并指定
use utf8;
位于脚本的顶部。
最后,还要将所有HTML模板保存为UTF-8,并从UTF-8编码的脚本生成所有输出,并将文档编码指定为UTF-8。所有其他路径都会导致精神错乱。
另外,请勿使用sexual
作为参数名称。使用名词作为参数和变量名。而且,对我来说,作为土耳其人的最令人愤怒的是,(Bay)先生和Bayan女士只是头衔,并且他们不适合询问受访者性别的输入领域。
另请参阅How can I deal with diverse gender identities in user profiles?目前在土耳其可能不会出现这种情况,但您最终会遇到此问题。
这是一个可能适合您的未经测试的脚本:
#!"c:\xampp\perl\bin\perl.exe"
use utf8;
use strict;
use warnings;
use warnings qw(FATAL utf8);
# Provides only object oriented interface
# without HTML generation cruft
use CGI::Simple;
run( CGI::Simple->new );
sub run {
my $cgi = shift;
binmode STDOUT, ':encoding(UTF-8)';
my ($name, $surname, $age, $gender) = map $cgi->param($_), qw(name surname age gender);
print $cgi->header(-type => 'text/plain', -charset => 'utf-8');
printf("%s %s %d %d kaydı, sistemde yapılacak olan güncellemelerden sonra sisteme başarıyla eklenecektir.\n",
$name , $surname , $age , $gender);
return;
}
答案 1 :(得分:1)
我认为您误解了charset
标题上Content-type
属性的用途。您的程序正在发出此标题:
Content-Type: text/plain; charset=ISO-8859-9
这说到HTTP客户端(例如浏览器)“我将向您发送一些编码为ISO-8859-9的纯文本”。但重要的是要注意标题纯粹是信息性的。它告诉全世界您的文本被编码为ISO-8859-9。 不为您执行编码。这取决于你。
这就是为什么鲍罗丁和其他人一直在问你一些你没有回答过的问题。大多数编辑器将创建以ISO-8859-1或UTF-8编码的文本。除非您有一个特殊的土耳其语编辑器或者您更改了编辑器的配置,否则您似乎不太可能在ISO-8859-9中生成文本。
如果您决定发出ISO-8859-9文本,那么您需要自己进行编码。您可以使用Encode模块中的encode()
函数来执行此操作。
use Encode;
my $encoded_text = encode('ISO-8859-9', $text);
print $encoded_text;
但我想知道你为什么要使用像ISO-8859-9这样相对模糊的编码。 UTF-8涵盖了土耳其语中使用的所有字符。为什么不用它呢?如果你采用与网络相同的标准,你的生活将变得容易得多。
顺便说一下,你在代码中引入了一个小小的陌生感。您在“函数”模式下使用CGI.pm并以一种将其大量函数导入命名空间的方式加载它。
use CGI qw(:standard);
然后以这种方式使用param()
函数几次。但之后,您创建一个CGI查询对象,以便在其上调用header()
方法。
my $q = new CGI;
print $q->header(...);
您可能没有意识到,但header()
函数包含在:standard
导入集中,因此您可以在不创建CGI对象的情况下调用它。
print header(...);
我在回答你之前的问题时就这样使用了它。我不确定你为什么改变代码使它变得更复杂。
我还应该指出,如果你想创建一个CGI查询对象,那么就不应该使用间接对象表示法:
my $q = new CGI;
这会在某些时候引起问题。写得好得多:
my $q = CGI->new;
(如the CGI.pm documentation中所示)