gpt4 book ai didi

php - 不区分重音的子字符串匹配

转载 作者:行者123 更新时间:2023-12-03 23:09:50 24 4
gpt4 key购买 nike

我有一个搜索功能,可以从 InnoDB 表(utf8_spanish_ci 排序规则)获取数据并将其显示在 HTML 文档(UTF-8 字符集)中。用户键入子字符串并获取匹配列表,其中第一个子字符串出现的位置突出显示,例如:

Matches for "AL":

Álava
<strong>Al</strong>bacete
<strong>Al</strong>mería
Ciudad Re<strong>al</strong>
Málaga

正如您从示例中看到的,搜索会忽略大小写和重音差异(MySQL 会自动处理)。但是,我用来突出显示匹配的代码无法执行后者:

<?php

private static function highlightTerm($full_string, $match){
$start = mb_stripos($full_string, $match);
$length = mb_strlen($match);

return
htmlspecialchars( mb_substr($full_string, 0, $start)) .
'<strong>' . htmlspecialchars( mb_substr($full_string, $start, $length) ) . '</strong>' .
htmlspecialchars( mb_substr($full_string, $start+$length) );
}

?>

有没有一种明智的方法来解决这个问题,而不意味着对所有可能的变化进行硬编码?

更新:系统规范为 PHP/5.2.14 和 MySQL/5.1.48

最佳答案

您可以使用Normalizer将字符串标准化为 Normalization Form KD (NFKD)其中字符被分解,因此 Á (U+00C1) 被分解为字母 A (U+0041) 和组合标记 的组合́ (U+0301):

$str = Normalizer::normalize($str, Normalizer::FORM_KD);

然后修改搜索模式以匹配这些可选标记:

$pattern = '/('.preg_replace('/\p{L}/u', '$0\p{Mn}?', preg_quote($term, '/')).')/ui';

然后使用 preg_replace 完成替换:

preg_replace($pattern, '<strong>$0</strong>', htmlspecialchars($str))

所以完整的方法是:

private static function highlightTerm($str, $term) {
$str = Normalizer::normalize($str, Normalizer::FORM_KD);
$pattern = '/('.preg_replace('/\p{L}/u', '$0\p{Mn}?', preg_quote($term, '/')).')/ui';
return preg_replace($pattern, '<strong>$0</strong>', htmlspecialchars($str));
}

关于php - 不区分重音的子字符串匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3582916/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com