使用 sqlite 的 FTS 片段函数处理 html 转义

Posted

技术标签:

【中文标题】使用 sqlite 的 FTS 片段函数处理 html 转义【英文标题】:handling html escaping with sqlite's FTS snippet function 【发布时间】:2012-11-22 01:20:16 【问题描述】:

我正在使用 sqlite 的全文搜索支持来存储可能包含 &<> 字符的文档。我打算使用 sn-p 函数来突出显示 html 结果页面的匹配项,但我没有看到在注入标记之前转义文本的明显方法。我宁愿在存储之前不要对文本进行转义,因为那样ampltgt 将成为标记。

我能想到的最简单的解决方法是在存储页面之前对页面进行转义,并使用自定义标记器首先取消转义 &<>

但是...由于snippet(foo) 的默认设置是使用<b></b>,这看起来确实是一个非常常见的用例,我相信必须有一种方法来处理这个问题无需在 C 中重新发明***。我是否忽略了更优雅的解决方案?

【问题讨论】:

【参考方案1】:

似乎 FTS 确实不处理文本中的标记(注意 <p> 是如何被切碎的):

> CREATE VIRTUAL TABLE test USING fts3(content TEXT);
> INSERT INTO test VALUES('<p>Isn''t this <font face="Comic Sans">funny</font>?');
> INSERT INTO test VALUES('blah');
> SELECT snippet(test) FROM test WHERE content MATCH 'funny';
p>Isn't this <font face="Comic Sans"><b>funny</b></font>?
> SELECT snippet(test) FROM test WHERE content MATCH 'font';
p>Isn't this <<b>font</b> face="Comic Sans">funny</<b>font</b>>?

存储文本的最简洁方式是纯文本,未转义。 但是,要正确突出显示搜索结果,您有两种选择:

使用snippet 的可选参数指定保证不会出现在文本中的标记(这可能是不可能的),并在转义时将它们转换为&lt;b&gt;... HTML 文本;或 改用offsets 函数并手动插入标记。

【讨论】:

谢谢!我存储的文本是 ReStructured Text (并且已经全部验证),所以我最终使用了被 docutils rst 解析器拒绝的标记。不漂亮,但效果很好。

以上是关于使用 sqlite 的 FTS 片段函数处理 html 转义的主要内容,如果未能解决你的问题,请参考以下文章

Peewee 可以使用 SQLite 的 FTS5(全文搜索)辅助函数 highlight() 吗?

安卓 SQLITE FTS 版本

SQLite3 FTS3/FTS4 匹配信息示例

PhoneGap、SQLite 和全文搜索

SQLite、FTS、MATCH 和分隔列中的文本

ios sqlite fts 扩展“没有这样的模块 fts4”错误