我有一个包含法语单词的数组:['É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
我在构造Collation对象时尝试了不同的组合,没有任何好结果:“fr-FR”,“fr-FR.UTF8”等。
还有什么我想念的吗?
答案 0 :(得分:5)
根据this blog post, cote ,coté,côte和côté(已用英语排序),法语排序顺序为: cote ,côte,coté和cô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é就是。在英语和大多数其他语言中,评估从左侧开始,因此CIRCUMFLEX或缺少“o”是订购的控制因素。
因此,如果您的数组中包含西班牙和美国,则它们将具有相同的英语和法语顺序。
您还应该记住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表示使用了默认的区域设置数据;无法找到所请求的区域设置或任何后备区域设置。
例如,当我使用 fr_FR 区域设置时,我得到一个U_USING_FALLBACK_WARNING,表示使用了回退区域设置,在这种情况下是区域设置 fr 。 / p>
看起来,您的计算机不支持法语(或者确实如此,但不管怎样,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中运行得很好,而且我没有安装任何软件包或配置任何东西。
答案 1 :(得分: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”之后。
所以,我认为这是一个文件编码。
答案 2 :(得分:0)
尝试'FR',它应该适用于您的系统我猜:
$collator = new Collator('FR');