【发布时间】:2010-10-11 11:28:01
【问题描述】:
我有许多正则表达式模式。输入字符串时,我必须找到与该字符串匹配的所有模式。这通常是一个 O(n) 操作:
SELECT regex FROM regexes WHERE 'string' RLIKE regex
最快的方法是什么?是否有针对执行此类操作进行优化的数据库结构或存储系统?
【问题讨论】:
标签: database regex search data-structures
我有许多正则表达式模式。输入字符串时,我必须找到与该字符串匹配的所有模式。这通常是一个 O(n) 操作:
SELECT regex FROM regexes WHERE 'string' RLIKE regex
最快的方法是什么?是否有针对执行此类操作进行优化的数据库结构或存储系统?
【问题讨论】:
标签: database regex search data-structures
如果适用于您的情况,您可以实施的一种优化是对您的正则表达式进行分类并将它们组织在层次结构中,以便:
您只需测试少数最通用的正则表达式。
对于任何匹配的通用正则表达式,然后继续针对同一类别的所有正则表达式测试字符串。
例如,如果您的输入字符串可以任意复杂,并且您有数千个正则表达式,您可以将它们组织成如下类别:
\d+ 类别,用于测试号码模式(SSN、电话号码等)
<.*?> 类别,用于测试是否存在 HTML 标记
\w+@\w+ 类别,可以测试电子邮件地址的存在
等等
如果任何根模式不匹配,那么您就不必测试无论如何都会失败的整个模式范围。
不知道这是否与您的确切域匹配,但这是一种可能的优化。
【讨论】:
简短的回答是“不”。目前在任何 DBMS 平台上都没有可用的索引结构来索引像这样的正则表达式的部分匹配。
长答案是通配符匹配的前导常量(例如'foo_')可以用作索引匹配的前缀。许多 DBMS 平台会对此进行优化并使用索引(如果可用)来解析前缀。然而,这并不像一个完整的正则表达式那么聪明,而且只有在你有一个常量前缀的情况下才能使用索引。
更长的答案是有诸如RETE 之类的算法可以优化这样的部分匹配。如果您可以将匹配项表示为前向链接生产规则而不是正则表达式,这可能适用。
Rete 的工作原理是计算部分匹配并仅显示可以从该部分匹配中达到的规则,因此它比 O(n) 更有效(更像 O(log n) 但我不确定确切的时间复杂性)用于将 n 条规则与事实相匹配。
【讨论】: