首先,不是bug而是功能well documented in the docs:
[]
用于表示一组字符。在一组中:
可以通过给出两个字符并用'-'分隔它们来表示字符范围,例如[az]将匹配任何小写ASCII字母,[0-5][0-9]将匹配所有两个-数字从 00 到 59,并且 [0-9A-Fa-f] 将匹配任何十六进制数字。 如果 - 被转义(例如 [a-z])或者如果它被放置为第一个或最后一个字符(例如 [a-]),它将匹配一个文字 '-'。
因此,在两个文字之间使用- 会将正则表达式评估为字符范围:
re.compile("[a-0]+")
>> error: bad character range
re.findall("[.-_]+", "asdasd-asdasdad._?asdasd-")
>> ['._?']
如您所见,当在字符集中的字符之间使用时,python 总是将- 解释为范围指示符。
正如(也)在文档中所述,通过使用 \- 转义 - 或将其作为字符集 [] 中的第一个或最后一个文字来避免范围声明
如果您想捕获包括- 在内的字符范围,请尝试:
re.findall("[.-_\-]+", "asdasd-asdasdad._?asdasd-")
>> ['-', '._?', '-']
注意: 当 LOCALE 和 UNICODE 标志未设置时,\w 等于 [a-zA-Z0-9_]。所以你不需要再次声明_
在你的情况下:
url(r'^user/(?P<username>[-.\w]+)/foo', 'myapp.views.foo')
url(r'^user/(?P<username>[.\w-]+)/foo', 'myapp.views.foo')
url(r'^user/(?P<username>[.\-\w]+)/foo', 'myapp.views.foo')
除了- 用法之外,如果您使用默认的Django 用户名样式,那么@navneet35371 对有效字符集是正确的。您可以更改您的正则表达式字符集以包含 @ 和 + 并使用
url(r'^user/(?P<username>[\w.@+-]+)/foo', 'myapp.views.foo')