我正在尝试比较两个字符串,比如说 Émilie 和 Zoey。好吧,'E' 出现在 'Z' 之前,但在 ASCII 图表上,Z 出现在 É 之前,所以正常if ( str1 > str2 )
不会工作。
我试过了if (strcmp(str1,str2) > 0)
还是不行。所以我正在寻找一种将字符串与 UTF-8 字符进行比较的本地方法。
我正在尝试比较两个字符串,比如说 Émilie 和 Zoey。好吧,'E' 出现在 'Z' 之前,但在 ASCII 图表上,Z 出现在 É 之前,所以正常if ( str1 > str2 )
不会工作。
我试过了if (strcmp(str1,str2) > 0)
还是不行。所以我正在寻找一种将字符串与 UTF-8 字符进行比较的本地方法。
重要的
此答案适用于无法运行/安装 '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 remove 重音: 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
// )
没有本地方法可以做到这一点,但是 PECL 扩展:http ://php.net/manual/de/class.collator.php
$c = new Collator('fr_FR');
if ($c->compare('Émily', 'Zoey') < 0) { echo 'Émily < Zoey'; }
我建议使用该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)
)
这里有一些对我有用的东西,虽然我不确定它是否可以用来比较其他语言的特殊字符。
我只是在使用该mb_strpos
功能并查看结果。我想这将尽可能接近 UTF8 字符串的原生比较:
if (mb_strpos(mb_strtolower($search_in), $search_for) !== false) {
//do stuff
}