Perl 下拉菜单和 Unicode

标签 perl unicode encoding utf-8

我已经研究这个问题有一段时间了,但不太明白。这是 Ubuntu 上的 Perl 5。我的网页上有一个下拉列表:

$output .= start_form . "Student: " . popup_menu(-name=>'student', -values=>['', @students], -labels=>\%labels, -onChange=>'Javascript:submit()') . end_form;

它只是来自 SQL Server 表的一组“姓、名”形式的名称。标签是从 SQL 列创建的,如下所示:

$labels{uc($record->{'id'})} = $record->{'lastname'} . ", " . $record->{'firstname'}; 

问题是下拉列表无法正确显示某些 Unicode 字符。例如,“Søren”在下拉列表中显示为“Sären”。我的标题中有:

use utf8;
binmode(STDOUT, ":utf8");

...我也尝试过对“decode( )”函数的各种处理,但无济于事。对我来说,有趣的是,如果我将 $labels 拉入测试脚本并将列表打印到控制台,则名称显示得很好!那么到底是什么导致了下拉呢?预先感谢您。

编辑:

这是相关的功能,我已将其简化为在控制台中运行的脚本,并且为具有 Unicode 字符的三个条目生成正确的结果:

#!/usr/bin/perl

use DBI;
use lib '/home/web/library';
use mssql_util;
use Encode;

binmode(STDOUT, ":utf8");

$query = "[SQL query here]";

$dbh  = &connect;
$sth  = $dbh->prepare($query);
$result = $sth->execute();

while ($record = $sth->fetchrow_hashref())
{
        if ($record->{'id'})
        {
                $labels{uc($record->{'id'})} = Encode::decode('UTF-8', $record->{'lastname'} . ", " . $record->{'nickname'} . " (" . $record->{'entryid'} . ")");
        }
}

$sth->finish();

print "$labels{'ST123'}\n";
print "$labels{'ST456'}\n";
print "$labels{'ST789'}\n";

生产脚本的不同之处在于,它不是像上面那样打印到控制台,而是打印到 HTTP:

$my_output = "<p>$labels{'ST123'}</p><br>
              <p>$labels{'ST456'}</p><br>
              <p>$labels{'ST789'}</p>";

$template =~ s/\$body/$my_output/;

print header(-cookie=>$cookie) . $template; 

这会在页面上给出诸如“Zoà”和“Sàren”之类的字符串。但是,如果我从生产脚本的顶部删除 binmode(STDOUT, ":utf8"); ,那么字符串在页面上显示得很好(即我得到“Zoë”和“Søren” )。

我相信在将 UTF-8 写入输出时 binmode( ) 行是必需的,但在这里删除它会产生正确的结果。给出了什么?

最佳答案

问题#1:解码输入

53.C3.B8.72.65.6ESøren 的 UTF-8 编码。当您指示 Perl 重新编码(通过打印它以使用 :utf8 层进行处理)时,您就会产生垃圾。

您需要解码您的输入($record->{id}$record->{lastname}$record->{firstname} 等)!这会将 UTF-8 字节 53.C3.B8.72.65.6E (“编码文本”)转换为 Unicode 代码点 53.F8.72.65.6E ( “解码后的文本”)。

在此形式中,您将能够使用 uc、正则表达式匹配等。您还可以将它们打印到带有编码层的句柄(例如 :encoding (UTF-8),或不正确的 :utf8)。

您透露这些输入来自数据库。大多数 DBD 都有一个导致字符串被解码的标志。例如,如果是 MySQL 数据库,则应将 mysql_enable_utf8mb4 => 1 传递给 connect


问题 #2:通信编码

如果您要输出 UTF-8,请不要告诉浏览器它是 ISO-8859-1!

$ perl -e'use CGI qw( :standard ); print header()'
Content-Type: text/html; charset=ISO-8859-1

已修复:

$ perl -e'use CGI qw( :standard ); print header( -type => "text/html; charset=UTF-8" )'
Content-Type: text/html; charset=UTF-8

关于Perl 下拉菜单和 Unicode,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46984007/

相关文章:

php - 如何在 PHP 中反序列化 Perl Data::Dumper 输出

python - 将 unicode 字符编码为 un​​icode 转义序列

java - Java 中的紧凑图像编码

regex - perl -pe 正则表达式问题

perl - Perl 中如何检查文件是否存在?

python - 在孟加拉语单词中查找音节的正则表达式

unicode - Emacs:自动将 LaTeX 替换为 Unicode 符号

PHP 文本编码/解码 (TinyMCE)

ios - Swift 无法分配给 NSData 类型的不可变值

perl - 当我用 perl (ubuntu10.10) 执行脚本时出了点问题