2

当我使用 dbi 从数据库中读取一些文本字段并将其存储在 $variable 上并在此变量上运行 lenght 函数时,我的 mysql 数据库被编码为 ut8_generic_ci 我得到一个数字长度

  my $data retrive_text_from_db(); #using dbi
  print length $data; 

但是当我将 $data 存储在文本文件中然后尝试在另一个脚本上读取它并运行长度函数时,我有时会得到不同的长度

     open T, '<'  ,'file.txt' or die $!;
     binmode(T, ":utf8");
     my $text;
     {local $/; $text=<T>; }
     print length $text; 

有人遇到过这个问题吗/有人能告诉我问题的根源是什么,我该如何解决?

4

2 回答 2

3

Perl 字符串要么是面向字节的,要么是面向字符的。我假设您第一个示例报告的长度总是大于或等于第二个示例报告的长度?

当您使用时,binmode(T, ":utf8")您告诉 Perl 获取文件中的字节流并使用 UTF-8 编码自动将它们转换为字符。所以在这个例子中$text应该是一个字符串。

我的猜测是您尚未配置 DBI 来执行此转换,因此您最终会得到一个包含 UTF-8 编码数据的字节字符串。这意味着某些字符可能每个需要 2-4 个字节。一种选择是将 DBI 配置为正确处理 UTF-8。如何做到这一点取决于驱动程序,因为您使用 MySQL,它应该通过这种方式连接:

my $dbh = DBI->connect($dsn, $user, $passwrod, { mysql_enable_utf8 => 1 });

由于某种原因,此配置变量的默认值似乎已关闭。

或者,您可以使用 Encode 模块自己进行转换:

use Encode;
$data = decode_utf8($data);
于 2012-09-26T12:56:16.570 回答
0

在这里尝试的第一件事是打印两者$data$text在屏幕上查看它们是否相同。如果您有字符编码问题,其中之一可能会失败。在这种情况下,请按照 pmakholm 的建议查看编码模块。

如果该测试成功,那就更微妙了。

其中一种可能性是换行符在输入数据和文本文件之间的存储方式不同。在某些格式中,换行符是一个字符;在其他情况下,它们是两个字符。即使数据实际上是相同的,这也会给你不同的长度。

于 2012-09-26T13:02:20.197 回答