突出显示搜索结果:RegEx 字符整理?
Highlighting Search Results: RegEx Character Collation?
当我 运行 全文 MySQL 查询时,多亏了 Unicode 字符排序规则,我将得到匹配以下所有内容的结果,无论我可能查询哪个:saka, sakā, śāka, ṣaka
等.
我遇到的问题是在搜索结果中突出显示匹配项。使用标准 RegEx,我只能匹配并突出显示结果中的原始查询词 -- 而不是所有整理的匹配项。
如何解决这个问题?我最初想到了这些方法:
- 创建一个 RegEx 模式来分析针对所有可能变体的目标结果。很容易变成一个臃肿的怪物。
- 创建结果的规范化版本,在那里找到匹配项,并使用字符串位置作为突出显示的基础。
然而,与常规搜索结果突出显示相比,这两种方法都会产生大量处理开销。第一种方法会产生巨大的 CPU 开销;第二个可能会吃得更少 CPU 但为了结果至少要消耗两倍的 RAM。有什么建议吗?
P.S。如果它是相关的:我正在处理的特定字符集(带有扩展名的梵语音译的 IAST)具有 L 和 N 的三种变体; M、R 和 S 的两个变体;以及 A、D、E、H、I、T 和 U 的一种变体;总共 A-Z + 19 个变音符号变体; + 大写字母(这里没有问题)。
使用 MySQL 及其 REGEXP,您只能定位与 REGEXP 匹配的行。您无法在列中找到匹配项。
REGEXP 和 LIKE 都遵循相关列的排序规则,但这无助于在该列中定位文本。
查看 MariaDB 及其 REGEXP_REPLACE。
MySQL 至少有一个与之相关的错误:
http://bugs.mysql.com/bug.php?id=70767
这是我最后做的。似乎对性能的影响可以忽略不计。 (我注意到 none!)
首先,将查询词转换为迭代变体的正则表达式的函数:
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|ā)
。然后,使用 variant-iterated word-pattern 来突出搜索结果:
$word = iast_normalize_regex($word);
$result = preg_replace("#({$word})#iu", "<b></b>", $result);
Presto:我突出显示了所有变体。感谢迄今为止的贡献,如果您能想到更好的方法来完成此任务,请告诉我。干杯!
当我 运行 全文 MySQL 查询时,多亏了 Unicode 字符排序规则,我将得到匹配以下所有内容的结果,无论我可能查询哪个:saka, sakā, śāka, ṣaka
等.
我遇到的问题是在搜索结果中突出显示匹配项。使用标准 RegEx,我只能匹配并突出显示结果中的原始查询词 -- 而不是所有整理的匹配项。
如何解决这个问题?我最初想到了这些方法:
- 创建一个 RegEx 模式来分析针对所有可能变体的目标结果。很容易变成一个臃肿的怪物。
- 创建结果的规范化版本,在那里找到匹配项,并使用字符串位置作为突出显示的基础。
然而,与常规搜索结果突出显示相比,这两种方法都会产生大量处理开销。第一种方法会产生巨大的 CPU 开销;第二个可能会吃得更少 CPU 但为了结果至少要消耗两倍的 RAM。有什么建议吗?
P.S。如果它是相关的:我正在处理的特定字符集(带有扩展名的梵语音译的 IAST)具有 L 和 N 的三种变体; M、R 和 S 的两个变体;以及 A、D、E、H、I、T 和 U 的一种变体;总共 A-Z + 19 个变音符号变体; + 大写字母(这里没有问题)。
使用 MySQL 及其 REGEXP,您只能定位与 REGEXP 匹配的行。您无法在列中找到匹配项。
REGEXP 和 LIKE 都遵循相关列的排序规则,但这无助于在该列中定位文本。
查看 MariaDB 及其 REGEXP_REPLACE。
MySQL 至少有一个与之相关的错误: http://bugs.mysql.com/bug.php?id=70767
这是我最后做的。似乎对性能的影响可以忽略不计。 (我注意到 none!)
首先,将查询词转换为迭代变体的正则表达式的函数:
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|ā)
。然后,使用 variant-iterated word-pattern 来突出搜索结果:
$word = iast_normalize_regex($word);
$result = preg_replace("#({$word})#iu", "<b></b>", $result);
Presto:我突出显示了所有变体。感谢迄今为止的贡献,如果您能想到更好的方法来完成此任务,请告诉我。干杯!