在Django中匹配嵌套路径时的灾难性正则表达式

时间:2012-03-19 15:11:43

标签: regex django

我在Django中有一个分层数据结构,并希望将路径与Django URL模式中的对象相匹配。这是我的模式:

url(r'^products/(?P<path>(?:[-\w]+\/?)+)/$',
    CategoriesListView.as_view(model=Product),
    name='product_categories_list'
),

目标是匹配整个路径,但没有尾部斜杠。问题是,在某些输入上,这个正则表达式在性能上完全退化。主要问题似乎是包含点的字符串:

In [1]: import re

In [2]: s = re.compile(r'^products/(?P<path>(?:[-\w]+/?)+)/$')

In [3]: s.search('products/111111111111111111111111.c')

大约需要5秒钟。使字符串更长会导致运行时间呈指数级增长。

如何重写该正则表达式,使其仍然匹配相同的字符串,但不吃早餐的CPU?

1 个答案:

答案 0 :(得分:2)

你可以写:

r'^products/(?P<path>[-\w/]+)/$'

匹配同一组字符串除外),它不强制禁止非终结//。如果禁令很重要,那么你可以写:

r'^products(?!.*//.)/(?P<path>[-\w/]+)/$'

使用负前瞻性断言以较便宜的方式强制执行该禁令。