我正在尝试比较两个字符串,比如 É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 moving去掉重音:不工作作为例外?为了使“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
// )
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
}