说我在db
中有以下一组网址url data
^(.*)google.com/search foobar
^(.*)google.com/alerts barfoo
^(.*)blah.com/foo/(.*) foofoo
... 100's more
考虑到野外的任何网址,我想查一查 看看该url是否属于一组现有的url并获取 相应的数据字段。
我的问题是:
答案 0 :(得分:1)
“2.django通过遍历每个正则表达式并检查匹配来进行urlresolution,因为可能有1000个url是最好的方法吗?”
“3。我可以看一下现有的实现吗?”
如果运行大量正则表达式确实是一个问题,那么你应该查看esmre,它是一个Python扩展模块,用于加速大量正则表达式。它的工作原理是提取每个正则表达式的固定字符串,并将它们放在Aho-Corasick启发的模式匹配器中,以快速消除几乎所有的工作。
答案 1 :(得分:0)
Django的优势在于其URL通常是分层的。虽然整个Django项目可能有100个或更多的URL,但它一次只能处理十几个或更少的模式。您的网址中是否有可以通过这种方式利用的任何结构?
除此之外,您可以尝试创建某种启发式方法。例如。找到你的模式的“固定”部分,然后消除其中的一些然后(通过简单的子字符串搜索),然后切换到正则表达式匹配。
在极端情况下,您可以创建产品自动机。这将是超级快,但内存要求可能是不切实际的(并可能在接下来的几个世纪保持如此)。
答案 2 :(得分:0)
在确定django方法无法工作之前,请尝试实施它并应用典型的工作负载。对于一个非常彻底的方法,你实际上可以计算每个正则表达式的成本,这可以指导你改进最昂贵和最常用的正则表达式。特别是,您可以将最常用,廉价的正则表达式安排到列表的前面。这可能是比发明一种新技术来解决你甚至不知道的问题更好的选择。
答案 3 :(得分:0)
在正则表达式的设计中,你当然需要更多的关注。例如,前缀^(.*)
将匹配任何输入 - 虽然您可能由于各种原因需要前缀来捕获组,但是拥有它会意味着您无法轻松地消除数据库中的任何URL 。
我同意TokenMacGuy关于正则表达式难以解决的评论,但根据问题的真实规模,情况可能并非完全没有希望。例如,对于要匹配的URL,则其第一个字符应匹配;例如,您可以通过说明输入中的哪个第一个字符与该URL匹配来预先过滤您的URL。因此,您有一个辅助表MatchingFirstCharacters
,它是初始字符和匹配该初始字符的URL之间的查找。 (这只有在你没有很多含糊不清的前缀时才有效,正如我在答案的第一段中提到的那样。)使用这种方法意味着你不必加载所有的正则表达式来完全匹配 - 只是至少第一个字符匹配的那些。我想这个想法可以进一步推广,但这对读者来说是一种练习; - )
答案 4 :(得分:0)
我倾向于的计划是选择域名+ tld的计划 一个url,使用它作为一个键来找出所有的正则表达式而不是循环 每个正则表达式子集都可以找到匹配。
我为此使用了两个表
class Urlregex(db.Model):
"""
the data field is structured as a newline separated record list
and each record is a space separated list of regex's and
dispatch key. Example of one such record
domain_tld: google.com
data:
^(.*)google.com/search(.*) google-search
"""
domain_tld = db.StringProperty()
data = db.TextProperty()
class Urldispatch(db.Model):
urlkey = db.StringProperty()
data = db.TextProperty()
因此,对于2 db读取和循环通过域特定url子集的成本 任何传入的网址都应该能够与大量网址进行匹配。