快速字符串匹配算法,支持简单的通配符

时间:2009-07-02 04:27:56

标签: c++ sqlite pattern-matching wildcard

我需要将输入字符串(URL)与字符串规则的大集合(1k-250k)匹配,并支持简单的通配符。

通配符支持的要求如下:

通配符(*)只能替换URL的“部分”。这是域,路径和参数的片段。例如,“* .part.part / * / part?part = part& part = *”。此规则的唯一例外是路径区域,其中“/ *”应与斜杠后的任何内容匹配。

示例:

  • * .site.com/* - 应与sub.site.com/home.html,sub2.site.com/path/home.html
  • 相匹配
  • sub.site。* / path / * - 应匹配sub.site.com/path/home.html,sub.site.net/path/home.html,但不匹配sub.site.com/home。 HTML

其他要求:

  • 快速查找(我意识到“快速”是一个相对术语。给定最大250k规则,如果可能的话,仍然在<1.5s 。)
  • 在现代桌面范围内工作(例如,不是服务器实施)
  • 能够返回0:n匹配给定输入字符串
  • 匹配将附加规则数据

任务的最佳系统/算法是什么?我将用C ++开发解决方案,规则本身存储在SQLite数据库中。

2 个答案:

答案 0 :(得分:2)

首先,你可以做的最糟糕的搜索之一是字符串“ .domain.com / path ”两端的通配符 - 我想你要去经常打这个案子。因此,我的第一个建议是在域存储在您的数据库中时反转域的顺序:com.domain.example / path1 / path2 / page.html。这样可以让你保持更加整洁,只在字符串的“单向”上使用通配符,这将提供更快的查找速度。

我认为约翰提到了一些关于如何在数据库中完成这一切的好点。如果这不起作用,我会在列表中使用C ++中的正则表达式库。我打赌你会得到最好的性能和最常用的正则表达式语法。

答案 1 :(得分:1)

如果我没弄错的话,你可以采用字符串规则并将其分解为域,路径和查询部分,就像它是一个URL一样。然后,您可以针对要测试的网址中的相应部分,将每个部分应用标准wildcard matching algorithm。如果所有部分都匹配,则规则匹配。

实施例

Rule: *.site.com/*
    domain => *.site.com
    path   => /*
    query  => [empty]

URL: sub.site.com/path/home.html
    domain => sub.site.com
    path   => /path/home.html
    query  => [empty]

Matching process:
    domain => *.site.com matches sub.site.com?     YES
    path   => /*         matches /path/home.html?  YES
    query  => [empty]    matches [empty]           YES

Result: MATCH

当您将规则存储在数据库中时,我会将它们存储在这三个部分中。如果你想要超速,你可以将*转换为%,然后使用数据库的本地LIKE操作为你进行匹配。然后你就会有一个像

这样的查询
SELECT *
FROM   ruleTable
WHERE  @urlDomain LIKE ruleDomain
   AND @urlPath   LIKE rulePath
   AND @urlQuery  LIKE ruleQuery

其中@urlDomain@urlPath@urlQuery是预准备语句中的变量。查询将返回与URL匹配的规则,如果没有匹配则返回空结果集。