比较UTF-8字符串

时间:2013-02-01 21:10:52

标签: php string utf-8 comparison

我试图比较两个字符串让我们说Émilie和Zoey。好的'E'出现在'Z'之前,但是在ASCII图表Z之前出现É所以正常if ( str1 > str2 )将不起作用。

我试过if (strcmp(str1,str2) > 0)仍然无法正常工作。所以我正在研究一种将字符串与UTF-8字符进行比较的本地方法。

4 个答案:

答案 0 :(得分:13)

重要

这个答案适用于无法运行/安装'intl'扩展名的情况,只能通过将重音字符替换为非重音字符来对字符串进行排序。 要根据特定区域设置对重音字符进行排序,使用Collator是一种更好的方法 - 有关详细信息,请参阅此问题的其他答案。

按PHP 5.2中的非重音字符排序

您可以尝试使用iconv()和// TRANSLIT选项将两个字符串转换为ASCII以删除重音字符;

$str1 = iconv('utf-8', 'ascii//TRANSLIT', $str1);

然后进行比较

请参阅此处的文档:

http://www.php.net/manual/en/function.iconv.php

[更新,回应@ Esailija的评论] 我忽略了// TRANSLIT以意想不到的方式翻译重音字符的问题。此问题中提到了此问题:php iconv translit for removing accents: not working as excepted?

为了使'iconv()'方法有效,我在下面添加了一个代码示例,它使用preg_replace()从结果字符串中删除所有非单词字符。

<?php

setLocale(LC_ALL, 'fr_FR');

$names = array(
   'Zoey and another (word) ',
   'Émilie and another word',
   'Amber',
);


$converted = array();

foreach($names as $name) {
    $converted[] = preg_replace('#[^\w\s]+#', '', iconv('UTF-8', 'ASCII//TRANSLIT', $name));
}

sort($converted);

echo '<pre>'; print_r($converted);

// Array
// (
//     [0] => Amber
//     [1] => Emilie and another word
//     [2] => Zoey and another word 
// )

答案 1 :(得分:11)

没有本地方法可以做到这一点,不过是PECL扩展:http://php.net/manual/de/class.collator.php

$c = new Collator('fr_FR');
if ($c->compare('Émily', 'Zoey') < 0) { echo 'Émily < Zoey'; }

答案 2 :(得分:0)

我建议使用 usort 函数,以避免修改值,并仍然正确比较它们。

示例:

<?php

setLocale(LC_ALL, 'fr_FR');

$names = [
   'Zoey and another (word) ',
   'Émilie and another word',
   'Amber'
];

function compare(string $a, string $b) {
    $a = preg_replace('#[^\w\s]+#', '', iconv('utf-8', 'ascii//TRANSLIT', $a));
    $b = preg_replace('#[^\w\s]+#', '', iconv('utf-8', 'ascii//TRANSLIT', $b));

    return strcmp($a, $b);
}

usort($names, 'compare');

echo '<pre>';
print_r($names);
echo '</pre>';

结果:

Array
(
    [0] => Amber
    [1] => Émilie and another word
    [2] => Zoey and another (word) 
)

答案 3 :(得分:-2)

这里有一些对我有用的东西,虽然我不确定它是否有助于比较其他语言的特殊字符。

我只是使用mb_strpos功能并查看结果。我想这可以与UTF8字符串的原生比较一样接近:

if (mb_strpos(mb_strtolower($search_in), $search_for) !== false) {
    //do stuff
}