2012-03-05 2 views
4

Когда я запускаю следующий код, он не входит в раздел «сделать что-то здесь»:Сравнение двух Unicode строк с Perl

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

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

Есть еще один способ для сравнения строк Unicode с Perl?

+2

Зачем вам нужен другой способ? Есть ли что-то, что вы ищете, что встроенные сравнения строк ('eq',' ne', 'gt',' lt', 'ge' и' le') не предоставляют? –

+2

Если строки равны (как они кажутся), я бы ожидал, что что-то здесь, блок здесь не будет введен. –

+6

Чтобы Perl мог видеть файл так, как вы, он должен был быть закодирован как UTF-8, и вам нужно было использовать 'use utf8; 'Предполагая, что вы это сделали, Perl будет делать кодовую точку путем сравнения строк кода , Какие у вас проблемы? Вам сначала нужно [нормализовать] (http://search.cpan.org/perldoc?Unicode::Normalize) их? – ikegami

ответ

13

Если у вас есть две строки 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"); 
} 

И это работает прекрасно. eq и ne будут сравнивать кодовую точку строки по кодовой точке.

Некоторые графемы (например, «& eacute;») могут быть созданы несколькими различными способами, поэтому вам может потребоваться сначала их представление normalize.

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' не являются хорошими переменными для lexicalize, потому что 'sort {fc ($ a) cmp fc ($ b)} @ list' никогда не будет работать. Кроме того, с нормализацией существует 33 синглтона, которые не являются вопросом упорядочения меток. Наконец, он может захотеть, чтобы какое-то сравнение лучше выполнялось с помощью объекта Unicode :: Collate, но мы не будем знать этого без пояснений. Я, я уверен, что у него есть программный литерал, он сравнивается с чем-то, что он читал из потока, и у него нет всех его ** utf8nesses ** во всех правильных местах. Не могу сказать, потому что фрагмент кода, который он дал, не говорит реальной истории. – tchrist

+1

@tchrist, Эти синглтоны не являются исключением из того, что я сказал. Эти синглтоны (например, KELVIN SIGN) имеют одну и ту же графему (визуальное представление) в виде букв (например, «LATIN CAPITAL LETTER K»), к которым они считаются равными. – ikegami

+0

Вы сказали: «Может быть составлен несколькими способами». Это предполагает что-то, связанное с объединением символов для меня, а синглтоны - это нечто другое. Однако они не очень важны. Аспект нормализации порядка следования обычно намного важнее, за исключением некоторых устаревших текстов со старыми синглтонами в них. – tchrist

Смежные вопросы