【问题标题】:Fast string matching algorithm with simple wildcards support具有简单通配符支持的快速字符串匹配算法
【发布时间】:2009-07-02 04:27:56
【问题描述】:

我需要使用简单的通配符支持将输入字符串 (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 规则,仍然在 如果可能。)
  • 在现代桌面范围内工作(例如,不是服务器实现)
  • 在给定输入字符串的情况下能够返回 0:n 匹配项
  • 比赛将附加规则数据

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

【问题讨论】:

    标签: c++ sqlite pattern-matching wildcard


    【解决方案1】:

    首先,你能做的最差的搜索之一是在字符串“.domain.com/path”的两端使用通配符——我想你会去的打这个案子很多。所以我的第一个建议是颠倒存储在数据库中的域的顺序:com.domain.example/path1/path2/page.html。这将使您保持更整洁,并且只在字符串的“一个方向”上使用通配符,这将提供更快的查找速度。

    我认为 John 提到了一些关于如何在您的数据库中完成这一切的要点。如果这不起作用,我将使用 C++ 中的正则表达式库来对抗列表。我敢打赌,这样你会得到最好的性能和最通用的正则表达式语法。

    【讨论】:

      【解决方案2】:

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

      示例

      规则:*.site.com/* 域 => *.site.com 路径 => /* 查询 => [空] 网址:sub.site.com/path/home.html 域 => sub.site.com 路径 => /path/home.html 查询 => [空] 匹配过程: 域 => *.site.com 匹配 sub.site.com?是的 path => /* 匹配 /path/home.html?是的 查询 => [空] 匹配 [空] 是 结果:匹配

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

      SELECT *
      FROM   ruleTable
      WHERE  @urlDomain LIKE ruleDomain
         AND @urlPath   LIKE rulePath
         AND @urlQuery  LIKE ruleQuery
      

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

      【讨论】:

      • 我以前认为 LIKE/GLOB 只能匹配输入模式,但不能匹配规则(例如列)本身的模式。这很好用。作为旁注,我实际上通过不打破规则而是让它们完成(并且根据 Chris Harris 的评论反转域)来获得更好的性能。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-24
      • 2015-06-22
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多