1

我无法比较两个非 ascii 字符串,尽管两个字符串在控制台上显示相同。以下是我尝试过的。请让我知道这里缺少什么代码,以便两个变量相等。

if($lineContent[7] ne $name) {
  /*Control coming to here*/
  print "###### Values MIS-MATCHED\n";
} else {
  print "###### Values MATCHED\n";
}

$lineContent[7]来自 CSV 文件

$name 来自 XML 文件

当 Putty 的控制台在默认字符集中时

CSV Val: ENB69-åºå°å±
XML Val: ENB69-åºå°å±

当 Putty 的控制台设置为 UTF-8 时

CSV Val: ENB69-基地局
XML Val: ENB69-基地局
4

3 回答 3

3
#!/usr/bin/perl

use warnings;
use strict;
use Encode;

binmode STDOUT, ":encoding(utf8)";
open F1, "<:utf8", "$ARGV[0]" or die "$!";
open F2, "<", "$ARGV[0]" or die "$!";

my $a1 = <F1>;
chomp $a1;
my $a2 = <F2>;
chomp $a2;

if ($a1 eq $a2) {
    print "$a1=$a2 is true\n";
} else {
    print "$a1=$a2 is false\n";
}

my $b = decode("utf-8", $a2);
if ($a1 eq $b) {
    print "$a1=$b is true\n";
} else { 
    print "$a1=$b is false\n";
}

我编写了上面列出的测试程序。并用一行创建一个文本文件:基地局。当你用这个文本文件运行程序时,你可以得到一个假和一个真。我不知道你的程序中有什么,但我猜 csv 文件是作为纯文本读取的,没有任何解析器或编码/解码过程,而 xml 文件必须由某个库解析,因此内部编码机制不同对于两个字符串变量,包括一些编码符号的前导字节。简而言之,您可以尝试对两个字符串变量之一进行编码或解码,并查看它们是否匹配。

顺便说一句,这是我在这里的第一个答案,希望对您有所帮助;-)

从您的转储结果来看,很明显。第一个变量存储9个字符,在其内部结构中以utf-8编码构造基地局。第二个变量在其内部结构中代表 3 个字符。它们具有相同的字节流,并且在字节流视图中相等,但在基于字符的比较中不相等。

使用解码/编码可以解决您的问题。

于 2012-09-05T08:35:32.323 回答
1

如果您知道您正在比较 unicode 字符串,就个人而言,我会更加小心。Unicode::Collate是作业的模块。

当然,您还应该阅读 tchrist 现在著名的关于在 Perl 中启用 unicode 的 SO 帖子,https: //stackoverflow.com/a/6163129/468327 ,但utf8::all在打开适当的 unicode 支持方面做得非常出色。请注意,更好的 unicode 处理被添加到版本中的 Perl 核心中,5.14所以我在这里也需要它。

最后,这是一个进行比较的快速脚本,当然您可以根据需要通过读取文件来填充变量:

#!/usr/bin/env perl

use v5.14;
use strict;
use warnings;

use utf8::all;
use Unicode::Collate;

my $collator = Unicode::Collate->new;

my $csv = "ENB69-基地局";
my $xml = "ENB69-基地局";

say $collator->eq($csv, $xml) ? "equal" : "unequal";
于 2012-09-05T13:11:56.680 回答
1

您的输入:

"ENB13-\345\237\272\345\234\260\345\261\200"
"ENB13-\x{57fa}\x{5730}\x{5c40}"

如您所见,这些显然不一样。具体来说,第一个是另一个的UTF-8编码。始终解码输入。始终对输出进行编码。

use strict;
use warnings;

use utf8;                             # Source code is saved as UTF-8
use open ':std', ':encoding(UTF-8)';  # Terminal expects UTF-8

my $name = "ENB69-基地局";

while ($line = <STDIN>) {
   chomp;
   my @lineContent = split /\t/, $line;
   print($lineContent[7] eq $name ?1:0, "\n");  # 1
}
于 2012-09-05T15:31:25.747 回答