【问题标题】:Turkish character not rendering properly土耳其语字符未正确呈现
【发布时间】:2017-09-29 18:39:03
【问题描述】:

我在 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;

我该如何解决这个问题?

【问题讨论】:

  • 您的代码文件使用什么编码?你告诉 Perl 了吗?
  • 说您使用ISO-8859-9 很好,但您还需要实际使用它。您的编辑器可能会在某处设置“编码”。
  • 你的 Perl 程序文件使用什么编码?
  • @mehfatitem:我知道您想使用 ISO-8859-9,但是您的源文件是如何编码的?通常使用 UTF-8 更为常见,因为它不是特定于语言的,并且不会将您限制为 128 个非英文字母,但您可以将其设置为保存在 ISO-8859-9 中。如果您不确定,请运行此代码use Data::Dumper; $Data::Dumper::Useqq = 1; $Data::Dumper::Terse = 1; print Dumper $text; 并显示结果。
  • @mehfatitem:请回答我关于你得到什么输出而不是正确输出的问题。

标签: windows apache perl character-encoding cgi


【解决方案1】:

首先:不要使用CGI.pm 中的 HTML 生成功能。使用这些会导致表示层混乱不堪。相反,请使用基于 Template Toolkit 的模板来分隔演示和功能。

第二,不要使用indirect object notation。即不写:

my $cgi = new CGI;

改为写

my $cgi = CGI->new

使用$q$query 来指代CGI 对象很奇怪,它起源于万维网的早期。当您从头开始学习时,没有理由继续使用它。

此外,鉴于您刚刚实例化了一个对象,请不要使用诸如 param 之类的普通 subs,也不要污染脚本的命名空间。使用以下方式访问参数值:

 my $value = $cgi->param('surname');

最后,如果您要在源代码中使用“有趣”的字符,例如 Ş,请将源代码保存为 UTF-8 并指定

 use utf8;

在脚本的顶部。

最后,还要将所有 HTML 模板保存为 UTF-8,并从以 UTF-8 编码的脚本生成所有输出,并将文档编码指定为 UTF-8。所有其他途径都会导致精神错乱。

另外,不要使用sexual 作为参数名称。使用名词作为参数和变量名。而且,作为土耳其人,最让我愤怒的是,Mr. (Bay) 和 Ms. (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;
}

【讨论】:

  • @mehfatitem:您在疏远大多数愿意回答您的人方面做得非常出色。您已经提出了 5 个问题,总共获得了 -4 票。你表现得像个脾气暴躁的夜总会保镖,很难相信你是个程序员。也许尝试写一个新问题而不是那么不愉快?如果您需要帮助,那么您真的需要回答我提出的问题:您的 Perl 程序文件的编码是什么,您在浏览器中看到的是什么而不是应该存在的?
  • 我不是程序员先解决这个问题。我是一名软件工程师。我这几天一直在研究perl。我认为你必须给出更令人满意的答案,而不是批评人。你不是一个有道德的警察。我问了一个关于土耳其语字符编码的问题。你跑题了。告诉你必须删除 #!"c:\xampp\perl\bin\perl.exe" 这段代码。但这离主题很远。你说问题出在“ş”字符上。我告诉过你 ş 是土耳其语字母表中的字符。你把话题说得太夸张了,把自己当作受害者
  • @victim Borodin 在此之后,如果不是关于软件,请停止添加评论。因为你偷了我的时间。
  • @mehfatitem:像鲍罗丁和我这样的人正在努力帮助你。但除非您回答我们提出的问题,否则我们无法为您提供帮助。
  • @mehfatitem:我很确定这是意外工作。您应该将use utf8 添加到您的代码中并正确编码输出。
【解决方案2】:

我认为您误解了 charset 标头上的 charset 属性的用途。您的程序正在发出此标头:

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所示)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-07
    • 1970-01-01
    • 1970-01-01
    • 2018-08-03
    • 1970-01-01
    • 2014-07-25
    • 2021-07-21
    相关资源
    最近更新 更多