我将如何设计一个db来包含一组可以与传入的URL匹配的url正则表达式(python)

时间:2009-07-17 22:27:50

标签: python regex url-routing

说我在db

中有以下一组网址
url                     data
^(.*)google.com/search   foobar
^(.*)google.com/alerts   barfoo
^(.*)blah.com/foo/(.*)   foofoo
... 100's more

考虑到野外的任何网址,我想查一查 看看该url是否属于一组现有的url并获取 相应的数据字段。

我的问题是:

  1. 我如何设计数据库来执行此操作
  2. django通过循环遍历每个正则表达式并检查匹配来进行urlresolution 鉴于可能有1000个网址是最好的方法吗?
  3. 我可以看一下现有的实现吗?

5 个答案:

答案 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子集的成本 任何传入的网址都应该能够与大量网址进行匹配。