使用perl比较两个Unicode字符串

6
当我运行下面的代码时,它没有进入“在此处执行某些操作”部分:
my $a ='µ╫P[┐╬♣3▀═<+·1╪מ└╖"ª';
my $b ='µ╫P[┐╬♣3▀═<+·1╪מ└╖"ª';

if ($a ne $b) {
    # do something here    
}

有没有其他方法可以使用Perl比较Unicode字符串?

2
为什么需要另一种方式?您是否正在寻找内置字符串比较(eqnegtltgele)无法提供的功能? - user554546
2
如果这些字符串相等(就像它们看起来的那样),那么我期望“在此处执行某些操作”块不会被执行。 - David Harris
6
为了让Perl像您一样看到文件,它必须被编码为UTF-8,并且您必须使用“use utf8;”。假设您已经这样做了,Perl将对字符串进行逐个码点的比较。您遇到了什么问题?您需要先归一化它们吗? - ikegami
1个回答

15

如果你有两个 Unicode 字符串(即 Unicode 代码点的字符串),那么你肯定已将文件保存为 UTF-8,并且你实际上有

use utf8;  # Tell Perl source code is UTF-8.

my $a = 'µ╫P[┐╬♣3▀═<+·1╪מ└╖"ª';
my $b = 'µ╫P[┐╬♣3▀═<+·1╪מ└╖"ª';

if ($a eq $b) {
    print("They're equal.\n");
} else {
    print("They're not equal.\n");
}

这很完美地运作了。eqne将逐个代码点比较字符串。

某些字形(例如"é")可以用多种不同的方式构建,因此您可能需要首先对它们的表示进行规范化

use utf8;  # Tell Perl source code is UTF-8.

use charnames          qw( :full );  # For \N{}
use Unicode::Normalize qw( NFC );

my $a = NFC("\N{LATIN SMALL LETTER E WITH ACUTE}");
my $b = NFC("e\N{COMBINING ACUTE ACCENT}");

if ($a eq $b) {
    print("They're equal.\n");
} else {
    print("They're not equal.\n");
}

最后,Unicode认为某些字符几乎等价,它们可以使用不同形式的规范化被视为相等。

use utf8;  # Tell Perl source code is UTF-8.

use charnames          qw( :full );  # For \N{}
use Unicode::Normalize qw( NFKC );

my $a = NFKC("2");
my $b = NFKC("\N{SUPERSCRIPT TWO}");

if ($a eq $b) {
    print("They're equal.\n");
} else {
    print("They're not equal.\n");
}

8
$a$b 不是好的变量来进行词法分析,因为这样 sort { fc($a) cmp fc($b) } @list 就永远不会起作用了。此外,在规范化中,有 33 个单字符,它们并不涉及标记的顺序问题。最后,他可能需要一些通过Unicode::Collate 对象更好地完成比较的方式,但如果没有澄清,我们就不知道了。我猜他手头有一个程序文本,他正在将其与从流中读取的某些内容进行比较,但他没有在所有正确的位置上使用 utf8nesses。由于他提供的代码片段没有透露真正的情况,所以无法确定。 - tchrist
1
@tchrist,这些单例并不例外于我所说的。这些单例(例如KELVIN SIGN)与它们被认为相等的字母(例如“LATIN CAPITAL LETTER K”)具有相同的字形(视觉表示)。 - ikegami
你说“可以用多种方式组合”。这让我想到了涉及字符组合的内容,而单例则是另一回事。虽然它们并不重要。但规范化中标记的排序方面通常更为重要,除非在某些包含旧单例的遗留文本中。 - tchrist
1
@tchrist,对我来说,在音乐、摄影和化学中遇到的情况,秩序只是构成要素之一。但由于您认为秩序是构成的主要因素,所以我在我的回答中将“composed”改为“built”。 - ikegami
如果我早点找到这个答案,尤其是你说的neeq比较是基于代码点的...... - Binarus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接