Сравнение двух строк юникода в PHP

Я застрял в сравнении двух строк Unicode в PHP, которые содержат специальный символ 'ö'. Одна строка происходит от $_GET, другая — это имя папки файловой системы (scandir()). Обе строки кажутся мне равными, что делает

var_dump($filter);
var_dump($tail . '/' . $k);

на них также показывает их равенство, но с разными длинами строк (?!):

string '/blöb' (length=7)
string '/blöb' (length=6)

Мой фрагмент, сравнивающий их, выглядит следующим образом:

if($filter == ($tail . '/' . $k)) {
    /* ... */
}

Что тут происходит?

Дополнительная информация: $tail – это пустая строка:

string '' (length=0)

person proximus    schedule 28.07.2011    source источник
comment
Что возвращает print_r(unpack("H*",$k)) в ваших двух случаях?   -  person Anders Lindahl    schedule 28.07.2011
comment
Помните, что некоторые файловые системы используют NFD (или близкие к нему), и вы, вероятно, имеете в виду NFC. Вам нужно нормализовать одно и то же, если вы хотите выполнить двоичное сравнение. Но делать бинарные сравнения с текстом не рекомендуется. Вам нужно использовать UCA для текстовых сравнений. См. мой выступление OSCON на семи языках по Unicode на прошлой неделе.   -  person tchrist    schedule 30.07.2011


Ответы (2)


См. здесь: http://en.wikipedia.org/wiki/Unicode_equivalence и используйте это: < a href="http://www.php.net/manual/en/class.normalizer.php" rel="nofollow">http://www.php.net/manual/en/class.normalizer.php< /а>

Возможно, у вас есть разложенный символ в более длинной строке, означающий o, а затем умляут, объединяющий символ, который перекрывает предыдущий символ.

Функция нормализатора исправит подобные вещи.

В качестве примечания вы всегда должны нормализовать свой ввод, если вы используете его для эквивалентности (например, имя пользователя - вы хотите убедиться, что два человека не выбирают одно и то же имя пользователя, даже если двоичное представление строки отличается ).

person Ariel    schedule 28.07.2011
comment
Этот ответ требует установки intl. Итак, если он у вас есть, то почему бы не использовать collator_compare? Я ищу ответ, который не использует intl... - person user9645; 03.08.2016
comment
@user9645 user9645 Итак, вы хотите обрабатывать строки Unicode со всей их огромной сложностью, фактически не устанавливая библиотеку, которая знает, как обрабатывать Unicode? Я не понимаю, как это возможно. - person Ariel; 04.08.2016
comment
Ариэль. Нет, я просто хочу альтернативу GNU intl. Это все. - person user9645; 04.08.2016
comment
@user9645 intl не является GNU, это из библиотеки ICU (первоначально написанной Talligent и IBM, а затем Sun), которая является окончательной библиотекой юникода и фактически является частью юникода. Больше никто ничего не использует. Вы можете попробовать iconv и uconv, но я не думаю, что это можно сделать, и они больше не поддерживаются. Можете ли вы сказать мне, почему вы хотите избежать intl? - person Ariel; 05.08.2016

Можете ли вы попробовать разобрать их через utf8_encode() и проверить их там? PHP не поддерживает Unicode, поэтому рекомендуется использовать utf8_encode/decode для некоторых основных функций Unicode.

http://php.net/manual/en/language.types.string.php

person Florian Margaine    schedule 28.07.2011
comment
Спасибо за ответ на мой вопрос. Я голосую за вас. - person Naeem Ul Wahhab; 07.12.2011