PHP-MySQL-将utf8(非英语)数据的拉丁(英语)格式输入匹配
作者:互联网
我在MySQL中维护音乐数据库,如何返回存储在例如人们搜索“ Tiesto”时会显示“Tiësto”吗?
如果有任何区别,所有数据都将存储在全文索引下.
我已经在PHP中使用Levenshtein和在SQL中使用REGEXP了-并不是为了解决这个问题,而是为了提高总体可搜索性.
PHP:
function Levenshtein($word) {
$words = array();
for ($i = 0; $i < strlen($word); $i++) {
$words[] = substr($word, 0, $i) . '_' . substr($word, $i);
$words[] = substr($word, 0, $i) . substr($word, $i + 1);
$words[] = substr($word, 0, $i) . '_' . substr($word, $i + 1);
}
$words[] = $word . '_';
return $words;
}
$fuzzyartist = Levenshtein($_POST['searchartist']);
$searchimplode = "'".implode("', '", $fuzzyartist)."'";
MySQL的:
SELECT *
FROM new_track_database
WHERE artist REGEXP concat_ws('|', $searchimplode);
另外,我经常在PHP中执行字符集转换和字符串清理,但是这些一直是另一种方式-标准化非拉丁字符.我无法专心执行相反的过程,而只能在某些情况下根据存储的数据进行.
解决方法:
一种可能的解决方案是在数据库中的“艺术家”旁边创建另一列,例如“ artist_normalized”.在这里,在填充表时,您可以插入字符串的“规范化”版本.然后可以针对artist_normalized列执行搜索.
测试代码:
<?php
$transliterator = Transliterator::createFromRules(':: NFD; :: [:Nonspacing Mark:] Remove; :: NFC;', Transliterator::FORWARD);
$test = ['abcd', 'èe', '€', 'àòùìéëü', 'àòùìéëü', 'tiësto'];
foreach($test as $e) {
$normalized = $transliterator->transliterate($e);
echo $e. ' --> '.$normalized."\n";
}
?>
结果:
abcd --> abcd
èe --> ee
€ --> €
àòùìéëü --> aouieeu
àòùìéëü --> aouieeu
tiësto --> tiesto
魔术是由Transliterator类完成的.指定的规则执行以下三个操作:分解字符串,删除变音符号,然后重新规范化字符串.
PHP中的Transliterator是建立在ICU之上的,因此您要依靠ICU库的表,这些表是完整且可靠的.
注意:此解决方案需要PHP 5.4或更高版本以及intl扩展名.
标签:php,mysql,search,regex,levenshtein-distance 来源: https://codeday.me/bug/20191009/1879272.html