我在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?
答案 0 :(得分:2)
你可以写:
r'^products/(?P<path>[-\w/]+)/$'
匹配同一组字符串(除外),它不强制禁止非终结//
。如果禁令很重要,那么你可以写:
r'^products(?!.*//.)/(?P<path>[-\w/]+)/$'
使用负前瞻性断言以较便宜的方式强制执行该禁令。