Сортировочный массив с сортировкой


У меня есть массив со словами на французском языке: ['États-Unis', 'Espagne' и т. Д.], Который я хотел бы отсортировать в алфавитном порядке в соответствии с его локализацией (fr_FR)

Я использую следующий код:

$collator = new Collator('fr-FR');
echo $collator->getErrorMessage();
$collator->asort($array);

Но я получаю сообщение об ошибке U_USING_DEFAULT_WARNING, когда я предполагаю, что используется английский или какой-либо другой язык. Что еще более важно, массив отсортирован неправильно (США появляются раньше Испании, если бы я ожидал, что произойдет обратное)

У меня установлен пакет intl, и моя система имеет соответствующие локали (Ubuntu)

$locale -a
C
C.UTF-8
en_US.utf8
es_ES.utf8
fr_FR
fr_FR.iso88591
fr_FR.utf8
POSIX

Я пробовал разные комбинации при построении объекта сортировки, без какого-либо хорошего результата: "fr-FR", "fr-FR.UTF8" и т. Д.

Есть ли что-нибудь еще, чего мне не хватает?

Author: Dan, 2012-11-26

3 answers

Согласно этому сообщению в блоге , для слов кот, котэ, кот и кот (уже отсортированы на английском языке), порядок сортировки на французском языке: кот, кот-д'ивуар, котэ и котэ. Приведенный ниже код сортирует слова во французском сопоставлении:

$words = array('cote', 'coté', 'côte',  'côté');
print_r($words);

$collator = new Collator('fr_FR');

// print info about locale
echo 'French Collation ' . (($collator->getAttribute(Collator::FRENCH_COLLATION) ==    Collator::ON) ? 'On' : 'Off') . "\n";
echo $collator->getLocale(Locale::VALID_LOCALE) . "\n";
echo $collator->getLocale(Locale::ACTUAL_LOCALE) . "\n";

$collator->asort($words);

print_r($words);

И напечатанный результат выглядит следующим образом:

Array
(
    [0] => cote
    [1] => coté
    [2] => côte
    [3] => côté
)
French Collation On
fr_FR
fr
Array
(
    [0] => cote
    [2] => côte
    [1] => coté
    [3] => côté
)

В том же сообщении в блоге автор говорит:

[...] диакритические знаки оцениваются справа налево, а не слева направо. Таким образом, кот появляется перед кот, а не после него, как это происходит в таких языках, как английский, которые оценивают их слева направо. Потому что слово кот не имеет ОСТРОЙ буквы "е" в конце слова, в то время как кот имеет. На английском и большинстве других языков оценка начинается слева, и поэтому ОКРУЖНОСТЬ или ее отсутствие на букве "о" является определяющим фактором в заказ.

Итак, если у вас есть массив со словами Испания и США, они будут иметь одинаковый порядок на английском и французском языках.

Вы также должны иметь в виду, что метод asort поддерживает ассоциацию индексов массива. Видите разницу:

asort:
Array
(
    [0] => cote
    [2] => côte
    [1] => coté
    [3] => côté
)

sort:
Array
(
    [0] => cote
    [1] => côte
    [2] => coté
    [3] => côté
)

О предупреждении об U_USING_DEFAULT_

В соответствии с этой документацией API:

U_USING_DEFAULT_WARNING указывает, что использовались данные локали по умолчанию; не удалось найти ни запрошенный язык, ни какой-либо из его резервных языков.

Когда я использую локаль fr_FR, например, я получаю предупреждение U_USING_FALLBACK_, которое указывает, что использовалась резервная локаль, в данном случае локаль fr.

Локаль

Как кажется, ваш компьютер не поддерживает французский язык (или поддерживает, но каким-то образом PHP не может его использовать, а затем вернуться к языку по умолчанию), хотя команда locale -a отображает французские пакеты. У меня есть несколько предложений, которые вы можете попробовать.

Сначала перечислите все поддерживаемые языки:

cat /usr/share/i18n/SUPPORTED 

Теперь сгенерируйте нужные вам языки:

sudo locale-gen fr_FR.UTF-8
sudo locale-gen fr_FR.ISO-8859-1
sudo dpkg-reconfigure locales

Если это не сработает, попробуйте установить пакеты language-pack-fr и language-support-fr и снова сгенерировать языки.

Эта проблема странная. У меня есть виртуальная машина с Ubuntu 11.04 и PHP 5.3.8, и она отлично работает, в моем Debian 6 тоже, и я не установил ни одного пакета или настроил что-нибудь.

 5
Author: mayconbordin, 2014-10-08 17:18:33

Я использую cygwin:

$ locale -a | grep fr_FR
fr_FR
fr_FR.utf8
fr_FR@euro

(обратите внимание, что у меня нет fr_FR.iso88591 на выходе)

Код (кодировка файла UTF-8):

$collator = new Collator('fr_FR');
var_dump($collator->getErrorMessage());

// FRENCH_COLLATION is OFF

$arr = array('États-Unis', 'Espagne');

var_dump($collator->getAttribute(Collator::FRENCH_COLLATION) == Collator::ON);
var_dump($collator->getLocale(Locale::VALID_LOCALE));
var_dump($collator->getLocale(Locale::ACTUAL_LOCALE));
$collator->asort($arr);
var_dump($arr);

// FRENCH_COLLATION is ON

$collator->setAttribute(Collator::FRENCH_COLLATION, Collator::ON);

$arr = array('États-Unis', 'Espagne');

var_dump($collator->getAttribute(Collator::FRENCH_COLLATION) == Collator::ON);
var_dump($collator->getLocale(Locale::VALID_LOCALE));
var_dump($collator->getLocale(Locale::ACTUAL_LOCALE));
$collator->asort($arr);
var_dump($arr);

Вывод:

string(23) "U_USING_DEFAULT_WARNING"
bool(false)
string(5) "fr_FR"
string(4) "root"
array(2) {
  [1]=>
  string(7) "Espagne"
  [0]=>
  string(11) "États-Unis"
}
bool(true)
string(5) "fr_FR"
string(4) "root"
array(2) {
  [1]=>
  string(7) "Espagne"
  [0]=>
  string(11) "États-Unis"
}

И вот в чем хитрость: Я конвертирую кодировку файла в ISO 8859-1 (в vim я делаю :set fileencoding=iso-8859-1) и повторяю попытку:

string(23) "U_USING_DEFAULT_WARNING"
bool(false)
string(5) "fr_FR"
string(4) "root"
array(2) {
  [0]=>
  string(10) "▒tats-Unis"
  [1]=>
  string(7) "Espagne"
}
bool(true)
string(5) "fr_FR"
string(4) "root"
array(2) {
  [0]=>
  string(10) "▒tats-Unis"
  [1]=>
  string(7) "Espagne"
}

Некоторые символы сломаны, но я думаю, это потому, что мой терминал не поддерживает данную кодовую страницу. Главное, что порядок строк сейчас именно такой, как вы описали: "Espagne" следует после "Этац-Унис".

Итак, я думаю, что это кодировка файла.

 0
Author: scriptin, 2012-12-01 14:20:08

Попробуйте просто "FR", это должно работать для вашей системы, я думаю:

$collator = new Collator('FR');
 0
Author: SergeyS, 2012-12-06 17:40:22