我正在玩pplog,一个单一的文件基础博客。
写入文件代码:
open(FILE, ">$config_postsDatabaseFolder/$i.$config_dbFilesExtension");
my $date = getdate($config_gmt);
print FILE $title.'"'.$content.'"'.$date.'"'.$category.'"'.$i; # 0: Title, 1: Content, 2: Date, 3: Category, 4: FileName
print 'Your post '. $title.' has been saved. <a href="?page=1">Go to Index</a>';
close FILE;
输入文字:
春眠不覺曉,處處聞啼鳥. 夜來風雨聲,花落知多小.
存储到文件后,它变为:
春眠不覺�›�,處處聞啼鳥. 夜來風�›�聲,花落知多小.
我可以使用Eclipse编辑文件并使其渲染正常。打印到文件期间存在问题。
一些基本信息: 草莓perl 5.12 不使用utf8; 尝试使用utf8;,没有效果。
谢谢。
---编辑--- 感谢您的评论。我追踪了代码:
代码添加新内容:
# Blog Add New Entry Page
my $pass = r('pass');
#BK 7JUL09 patch from fedekun, fix post with no title that caused zero-byte message...
my $title = r('title');
my $content = '';
if($config_useHtmlOnEntries == 0)
{
$content = bbcode(r('content'));
}
else
{
$content = basic_r('content');
}
my $category = r('category');
my $isPage = r('isPage');
sub r
{
escapeHTML(param($_[0]));
}
将命令转发到CGI.pm函数。
在CGI.pm
sub escapeHTML {
# hack to work around earlier hacks
push @_,$_[0] if @_==1 && $_[0] eq 'CGI';
my ($self,$toencode,$newlinestoo) = CGI::self_or_default(@_);
return undef unless defined($toencode);
$toencode =~ s{&}{&}gso;
$toencode =~ s{<}{<}gso;
$toencode =~ s{>}{>}gso;
if ($DTD_PUBLIC_IDENTIFIER =~ /[^X]HTML 3\.2/i) {
# $quot; was accidentally omitted from the HTML 3.2 DTD -- see
# <http://validator.w3.org/docs/errors.html#bad-entity> /
# <http://lists.w3.org/Archives/Public/www-html/1997Mar/0003.html>.
$toencode =~ s{"}{"}gso;
}
else {
$toencode =~ s{"}{"}gso;
}
# Handle bug in some browsers with Latin charsets
if ($self->{'.charset'}
&& (uc($self->{'.charset'}) eq 'ISO-8859-1' # This line cause trouble. it treats Chinese chars as ISO-8859-1
|| uc($self->{'.charset'}) eq 'WINDOWS-1252')) {
$toencode =~ s{'}{'}gso;
$toencode =~ s{\x8b}{‹}gso;
$toencode =~ s{\x9b}{›}gso;
if (defined $newlinestoo && $newlinestoo) {
$toencode =~ s{\012}{ }gso;
$toencode =~ s{\015}{ }gso;
}
}
return $toencode;
}
进一步追踪问题,发现浏览器默认为iso-8859-1,甚至手动设置为utf-8,它将字符串发送回服务器为iso-8859-1。
最后,
print header(-charset => qw(utf-8)), '<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
添加-charset =&gt; qw(utf-8)param to header。中国诗仍然是中国诗。
感谢Schwern的评论,它激励我找出问题并学习leeson。
答案 0 :(得分:2)
为了让utf8真正在Perl中工作,需要翻转很多个人功能。 use utf8
只使代码utf8(字符串,变量,正则表达式......),你必须单独执行文件句柄。
它很复杂,最简单的方法是使用utf8::all,这将使utf8成为代码,文件,@ ARGV,STDIN,STDOUT和STDERR的默认值。在Perl中,utf8支持不断改进,utf8 :: all将在可用时添加它。
答案 1 :(得分:0)
我不确定您的代码如何产生该输出 - 例如,缺少引号。当然,这可能是由于文件和我看到页面之间的“腐败”。 SO可以过滤损坏的UTF-8。我建议将来提供十六进制转储!
无论如何,要在Perl中使用UTF-8输出,有几种方法:
使用字符数据,即让Perl知道您的变量包含Unicode。这可能是最好的方法。确认utf8::is_utf8($var)
为真(您不需要,而不应 use utf8
为此)。如果没有,请查看Encode
模块的decode
函数,以使Perl知道其Unicode。一旦Perl知道您的数据是字符,那么该打印将发出警告(您确实启用了它,对吧?)。要解决此问题,请在文件上启用:utf8
或:encoding(utf8)
图层(后一版本提供错误检查)。您可以在打开(open FILE, '>:utf8', "$fname"
)中执行此操作,也可以使用binmode(binmode FILE, ':utf8'
)启用它。请注意,您还可以使用其他编码;请参阅encoding
和PerlIO::encoding
文档。
将您的Unicode视为不透明的二进制数据。 utf8::is_utf8($var)
必须是假的。操纵琴弦时一定要非常小心;例如,如果你有UTF-16-BE,那么这不是一个好主意:print "$data\n"
,因为你实际上需要print $data\0\n"
。 UTF-8的问题较少,但您需要了解它们。
我建议阅读perluniintro,perlunitut,perlunicode和perlunifaq manpages / pods。
此外,use utf8;
只告诉Perl你的脚本是用UTF-8编写的。它的影响非常有限;看它的pod文档。
答案 2 :(得分:0)
您没有显示实际运行的代码。我使用Cygwin上的5.10.1和Windows上的5.12.3成功处理了您提供的文本作为输入。所以我怀疑你的代码中有一个错误。尝试通过编写一个简短,独立的测试用例来缩小问题范围。