我需要将输入字符串(URL)与字符串规则的大集合(1k-250k)匹配,并支持简单的通配符。
通配符支持的要求如下:
通配符(*)只能替换URL的“部分”。这是域,路径和参数的片段。例如,“* .part.part / * / part?part = part& part = *”。此规则的唯一例外是路径区域,其中“/ *”应与斜杠后的任何内容匹配。
示例:
其他要求:
任务的最佳系统/算法是什么?我将用C ++开发解决方案,规则本身存储在SQLite数据库中。
答案 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匹配的规则,如果没有匹配则返回空结果集。