6

我在编码方面不太好,我想弄清楚如何以与开始时相同的编码返回数据......

我有一个包含一些字符的文件,例如当'»'我编辑并插入数据库时​​,它们已经变成了 »。

decode_entities() 什么都不做,并且 encode_entities 再次对字符进行编码。所以我创建了我自己的子来解决这个问题,但是当从文件中获取数据时,它没有以正确的格式检索。

my $file = "c:/perlscripts/" . md5_hex($md5Con) . "-code.php";
{
    local( $/ ); # undefine the record seperator
    open FILE, "<", $file or die "Cannot open:$!\n";
    my $fileContents = unicodeConvert(<FILE>);
    ...
    .. 

是否没有像这样的编码选项;

my $file = "c:/perlscripts/" . md5_hex($md5Con) . "-code.php";
{
    local( $/ ); # undefine the record seperator
    open FILE, "<", $file or die "Cannot open:$!\n", "UTF-8";
    my $fileContents = unicodeConvert(<FILE>);
    ...
    .. 

我的潜艇是;

sub unicodeConvert($) {
   my $str = shift;
    my %entityRef = ("&" => "&amp;", '¢' => "&cent;", '¤' => "&curren;", '¦' => "&brvbar;", '¨' => "&uml;", 'ª' => "&ordf;", '¬' => "&not;", '®' => "&reg;", '°' => "&deg;", '²' => "&sup2;", '´' => "&acute;", '¶' => "&para;", '¸' => "&cedil;", 'º' => "&ordm;", '¼' => "&frac14;", '¾' => "&frac34;", 'À' => "&Agrave;", 'Â' => "&Acirc;", 'Ä' => "&Auml;", 'Æ' => "&AElig;", 'È' => "&Egrave;", 'Ê' => "&Ecirc;", 'Ì' => "&Igrave;", 'Î' => "&Icirc;", 'Ð' => "&ETH;", 'Ò' => "&Ograve;", 'Ô' => "&Ocirc;", 'Ö' => "&Ouml;", 'Ø' => "&Oslash;", 'Ú' => "&Uacute;", 'Ü' => "&Uuml;", 'Þ' => "&THORN;", 'à' => "&agrave;", 'â' => "&acirc;", 'ä' => "&auml;", 'æ' => "&aelig;", 'è' => "&egrave;", 'ê' => "&ecirc;", 'ì' => "&igrave;", 'î' => "&icirc;", 'ð' => "&eth;", 'ò' => "&ograve;", 'ô' => "&ocirc;", 'ö' => "&ouml;", 'ø' => "&oslash;", 'ú' => "&uacute;", 'ü' => "&uuml;", 'þ' => "&thorn;", '¡' => "&iexcl;", '£' => "&pound;", '¥' => "&yen;", '§' => "&sect;", '©' => "&copy;", '«' => "&laquo;", '¯' => "&macr;", '±' => "&plusmn;", '³' => "&sup3;", 'µ' => "&micro;", '·' => "&middot;", '¹' => "&sup1;", '»' => "&raquo;", '½' => "&frac12;", '¿' => "&iquest;", 'Á' => "&Aacute;", 'Ã' => "&Atilde;", 'Å' => "&Aring;", 'Ç' => "&Ccedil;", 'É' => "&Eacute;", 'Ë' => "&Euml;", 'Í' => "&Iacute;", 'Ï' => "&Iuml;", 'Ñ' => "&Ntilde;", 'Ó' => "&Oacute;", 'Õ' => "&Otilde;", '×' => "&times;", 'Ù' => "&Ugrave;", 'Û' => "&Ucirc;", 'Ý' => "&Yacute;", 'ß' => "&szlig;", 'á' => "&aacute;", 'ã' => "&atilde;", 'å' => "&aring;", 'ç' => "&ccedil;", 'é' => "&eacute;", 'ë' => "&euml;", 'í' => "&iacute;", 'ï' => "&iuml;", 'ñ' => "&ntilde;", 'ó' => "&oacute;", 'õ' => "&otilde;", '÷' => "&divide;", 'ù' => "&ugrave;", 'û' => "&ucirc;", 'ý' => "&yacute;", 'ÿ' => "&yuml;");
    while( ( my $key, my $obj ) = each( %entityRef ) ) {
        if( $key ne '&' ) {
                $str =~ s/$key/$obj/gis
        } else {
                $str =~ s#&((?!(quot;)|(amp;)|(cent;)|(curren;)|(brvbar;)|(uml;)|(ordf;)|(not;)|(reg;)|(deg;)|(sup2;)|(acute;)|(para;)|(cedil;)|(ordm;)|(frac14;)|(frac34;)|(Agrave;)|(Acirc;)|(Auml;)|(AElig;)|(Egrave;)|(Ecirc;)|(Igrave;)|(Icirc;)|(ETH;)|(Ograve;)|(Ocirc;)|(Ouml;)|(Oslash;)|(Uacute;)|(Uuml;)|(THORN;)|(agrave;)|(acirc;)|(auml;)|(aelig;)|(egrave;)|(ecirc;)|(igrave;)|(icirc;)|(eth;)|(ograve;)|(ocirc;)|(ouml;)|(oslash;)|(uacute;)|(uuml;)|(thorn;)|(iexcl;)|(pound;)|(yen;)|(sect;)|(copy;)|(laquo;)|(macr;)|(plusmn;)|(sup3;)|(micro;)|(middot;)|(sup1;)|(raquo;)|(frac12;)|(iquest;)|(Aacute;)|(Atilde;)|(Aring;)|(Ccedil;)|(Eacute;)|(Euml;)|(Iacute;)|(Iuml;)|(Ntilde;)|(Oacute;)|(Otilde;)|(times;)|(Ugrave;)|(Ucirc;)|(Yacute;)|(szlig;)|(aacute;)|(atilde;)|(aring;)|(ccedil;)|(eacute;)|(euml;)|(iacute;)|(iuml;)|(ntilde;)|(oacute;)|(otilde;)|(divide;)|(ugrave;)|(ucirc;)|(yacute;)|(yuml;)|(nbsp;)))#$obj#gis;   
        }
    }
    return $str;
}
4

2 回答 2

8

正如对您问题的评论中所述,我不确定您到底在问什么。

所以我假设您正在尝试将 Unicode 字符转换为 HTML 实体。在这种情况下,使用其中一个预制模块应该会更好。如果由于编码问题(这在 Perl 中非常棘手)而无法正常工作,那么您的问题的答案是:

是否没有像这样的编码选项

open FILE, "<", $file or die "Cannot open:$!\n", "UTF-8";

... 可能会解决它,它也可能会使您自己的尝试工作,但最好使用现成的 ;-) (顺便说一下,您在那里编写它的方式是“UTF-8 " 选项die让你很难理解你在问什么 ;-)

是的,有一个 UTF-8 选项,假设你有一个最近的perl(>= v5.8):

open(my $fh,'<:encoding(UTF-8)', $file) or die "Error opening $file: $!";

(示例改编自perluniintro

您还可以使用binmode更改已打开的文件句柄(例如 STDIN/OUT)。

binmode(STDOUT, ":encoding(UTF-8)");

您还可以使用open pragma 设置默认编码。

但为此,我建议尝试binmode或更改您的开放线路,看看是否可以解决它。

如果您的perl版本低于 v5.8,事情会比较棘手,但如果您告诉我们版本,也许可以解决。

顺便说一句,我注意到的其他几件事:

  • 不是必需的,但使用词法范围的文件句柄(my $fh而不是FILE)被认为更好。
  • 当您在die字符串上添加换行符时,它会抑制通常添加以帮助您查找问题的行号信息。
  • 如果您将无法打开的文件的名称(或失败的 SQL 等)放在 die 消息中,则调试起来会更容易。
  • 不要在 Perl (5) 中使用子原型: ( sub unicodeConvert($))。不要把$/ @/%等放在那里。它不只是检查事物,它可能会以令人困惑的方式改变含义。只需要创建新的“内置样式”操作符。
于 2010-02-08T16:04:38.320 回答
1

我怀疑,您的终端字符集(可以是 UTF-8)和 perl 脚本的源代码(您可能在 8859-1 中的某些字符集感知编辑器中编辑)的字符集有所不同。如果您确定您的终端和源代码在同一个字符集中,请尝试放入use utf8;您的脚本标题(请参阅man perlunicode)。如果这没有帮助,请尝试打印存储到数据库中的数据(增加 DBI 的调试日志记录)(可能不相关,因为您不将数据存储为 UTF8)。一般来说,尽量提供:

  1. locale如果您为终端(或服务器使用的系统区域设置,如果您从例如 apache 启动它)执行脚本,则终端的代码页 ( )
  2. 源代码的字符集。
  3. MySQL 连接代码页(您发出SET NAMES 'utf8'吗?)

同样对于 HTML 编码,您可能会发现更容易重用HTML::Entities::decode()/HTML::Entities::encode()而不是自己实现它。

于 2010-02-08T11:15:15.690 回答