当我运行全文MySQL查询时,由于Unicode字符排序,我将获得与以下所有内容匹配的结果,无论我查询的是哪个:saka, sakā, śāka, ṣaka
等。
我遇到的问题是突出显示搜索结果中的匹配项。使用标准RegEx,我只能匹配并突出显示结果中的原始查询词 - 而不是所有整理的匹配。
如何解决这个问题呢?我最初想到了这些方法:
然而,与常规搜索结果突出显示相比,这两种方法都会产生大量的处理开销。第一种方法会产生强大的CPU开销;第二个可能会占用较少的CPU但是至少会为结果占用两倍的RAM。有什么建议吗?
P.S。如果它是相关的:我处理的特定字符集(IAST用于具有扩展的梵语音译)具有L和N的三种变体; M,R和S的两种变体; A,D,E,H,I,T和U的一种变体;总共A-Z + 19个变音变体; +大写(这里没有问题)。
答案 0 :(得分:2)
使用MySQL及其REGEXP,您只能找到与REGEXP匹配的行。您无法在列中找到匹配项。
REGEXP和LIKE都尊重相关列的排序规则,但这对于使用列定位文本没有帮助。
查看MariaDB及其REGEXP_REPLACE。
MySQL至少有一个与之相关的错误: http://bugs.mysql.com/bug.php?id=70767
答案 1 :(得分:2)
这是我最终做的事情。似乎对性能的影响可以忽略不计。 (我没注意到!)
首先,将查询词转换为迭代变体的正则表达式的函数:
function iast_normalize_regex($str) {
$subst = [
'a|ā', 'd|ḍ', 'e|ӗ', 'h|ḥ', 'i|ī', 'l|ḷ|ḹ', 'm|ṁ|ṃ',
'n|ñ|ṅ|ṇ', 'r|ṛ|ṝ', 's|ś|ṣ', 't|ṭ', 'u|ū'
];
$subst_rex = [];
foreach($subst as $variants) {
$chars = explode('|', $variants);
foreach($chars as $char) {
$subst_rex[$char] = "({$variants})";
}
}
$str_chars = str_split_unicode($str);
$str_rex = '';
foreach($str_chars as $char) {
$str_rex .= !isset($subst_rex[$char]) ? $char : $subst_rex[$char];
}
return $str_rex;
}
将单词saka
,śaka
等转换为(s|ś|ṣ)(a|ā)k(a|ā)
。然后,使用变体迭代的单词模式突出显示搜索结果:
$word = iast_normalize_regex($word);
$result = preg_replace("#({$word})#iu", "<b>$1</b>", $result);
Presto:我突出了所有变种。感谢您迄今为止的贡献,如果您能想出更好的方法来实现这一点,请告诉我。干杯!