8

我有一个带有法语单词的数组:['États-Unis', 'Espagne', etc] 我想根据其语言环境(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

我在构造 Collat​​ion 对象时尝试了不同的组合,但没有任何好的结果:“fr-FR”、“fr-FR.UTF8”等。

还有什么我想念的吗?

4

3 回答 3

6

根据这篇博文,对于单词cotecotecôtecôté(已经用英文排序),法语的排序顺序是:cotecôtecotecôté。下面的代码对法语排序规则中的单词进行排序:

$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é
)

在同一篇博文中,作者说:

[...] 变音符号是从右到左而不是从左到右评估的。因此côte 出现在coté之前,而不是像英语这样从左到右评估它们的语言中那样因为单词 côte 在单词末尾的“e”上没有 ACUTE,而coté有。在英语和大多数其他语言中,评估从左侧开始,因此“o”上的 CIRCUMFLEX 或缺少它是排序的控制因素。

因此,如果您有一个包含SpainUS的数组,它们在英语和法语中将具有相同的顺序。

您还应该记住,该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_WARNING

根据此API 文档

U_USING_DEFAULT_WARNING 表示使用了默认的语言环境数据;既找不到请求的语言环境,也找不到它的任何后备语言环境。

例如,当我使用fr_FR语言环境时,我得到一个 U_USING_FALLBACK_WARNING,这表明使用了一个备用语言环境,在本例中为语言环境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-frlanguage-support-fr并再次生成语言。

这个问题很奇怪。我有一个带有 Ubuntu 11.04 和 PHP 5.3.8 的虚拟机,它在我的 Debian 6 中也能正常工作,而且我没有安装任何软件包或配置任​​何东西。

于 2012-11-30T14:05:09.593 回答
0

我正在使用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”在“États-Unis”之后。

所以,我认为这是一种文件编码。

于 2012-12-01T14:20:08.743 回答
0

试试'FR',我猜它应该适用于你的系统:

$collator = new Collator('FR');
于 2012-12-06T17:40:22.170 回答