如何使此正则表达式 URL 模式在 Django 2 中工作
How do I make this regex URL pattern work in Django 2
我需要制作一个 URL 模式可以用于此 URL:
mysite.com/blog/12/بلاگ-مثال
它包含 utf-8 字符所以我尝试使用 \X
:
re_path(r'^blog/?P<blog_id>[\d+]+/(?P<slug>[\X.*]+)/$', views.single_blog, name='single_blog')
但是没有用。我不知道为什么。也许只是因为我不擅长正则表达式。所以我尝试了一种不同的模式,只使用 .*
来接受任何东西:
re_path(r'^blog/?P<blog_id>[\d+]+/(?P<slug>[.*]+)/$', views.single_blog, name='single_blog')
但这也行不通,我得到:
The current path, blog/12/بلاگ-مثال, didn't match any of these.
正如我提到的,我不擅长正则表达式,解决这个问题的正确方法是什么?
现在是时候说 now I have two problems 还是正则表达式是唯一的方法?
您的匹配方法无效,因为 Python re
不支持 \X
并且 [.*]+
匹配 1+ 个点或星号,但不匹配任何字符(因为您将 .*
放入 [...]
字符 class 中,它们表示文字符号,而不是特殊字符)。
此外,[\d+]+
也是一个字符class匹配任意数字或+
,1次或多次,所以也有问题。
您可以使用 [^/]
否定字符 class 来匹配任何字符,但 /
:
r'^blog/(?P<blog_id>\d+)/(?P<slug>[^/]+)/?$'
详情
^
- 输入开始
blog/
- 文字子字符串
(?P<blog_id>\d+)
- 组 "blog_id":1+ 位数
/
- 一个/
(?P<slug>[^/]+)
- 组 "slug":/
以外的 1+ 个字符
/?
- 一个可选的 /
$
- 字符串结尾。
Here is a regex demo(注意阿拉伯文字中的突出显示字符在那里不起作用。)
Is it the right time to say now I have two problems ...
事实上,您为这项任务选择了正确的工作。
另一个答案似乎有效,但不能容忍其中包含 波斯语 这个词。我发布此答案是为了说明为什么您自己的正则表达式无法按预期工作。
?P<blog_id>[\d+]+
可能您在这里指的是命名组,与您稍后在正则表达式中使用的组相同。您错过了左括号和右括号:(?P<blog_id>[\d+]+)
。另外 [\d+]
表示一个字符 class 由数字和 +
组成。您需要删除 +
:(?P<blog_id>[0-9]+)
(?P<slug>[\X.*]+)
结构很好,但字符 class 不是。 \X
在字符 class 中没有特殊含义,更不用说 Python 甚至不支持它的 re
模块了。 .*
也不例外。在字符中 class 几乎所有特殊标记都按字面意思处理。
所以 [\X.*]
匹配 X
或 .
或星号 *
。您需要将其更改为更通用的内容,例如 [^/]+
,这意味着匹配第一个斜杠(= 匹配除正斜杠之外的任何内容)。
我需要制作一个 URL 模式可以用于此 URL:
mysite.com/blog/12/بلاگ-مثال
它包含 utf-8 字符所以我尝试使用 \X
:
re_path(r'^blog/?P<blog_id>[\d+]+/(?P<slug>[\X.*]+)/$', views.single_blog, name='single_blog')
但是没有用。我不知道为什么。也许只是因为我不擅长正则表达式。所以我尝试了一种不同的模式,只使用 .*
来接受任何东西:
re_path(r'^blog/?P<blog_id>[\d+]+/(?P<slug>[.*]+)/$', views.single_blog, name='single_blog')
但这也行不通,我得到:
The current path, blog/12/بلاگ-مثال, didn't match any of these.
正如我提到的,我不擅长正则表达式,解决这个问题的正确方法是什么?
现在是时候说 now I have two problems 还是正则表达式是唯一的方法?
您的匹配方法无效,因为 Python re
不支持 \X
并且 [.*]+
匹配 1+ 个点或星号,但不匹配任何字符(因为您将 .*
放入 [...]
字符 class 中,它们表示文字符号,而不是特殊字符)。
此外,[\d+]+
也是一个字符class匹配任意数字或+
,1次或多次,所以也有问题。
您可以使用 [^/]
否定字符 class 来匹配任何字符,但 /
:
r'^blog/(?P<blog_id>\d+)/(?P<slug>[^/]+)/?$'
详情
^
- 输入开始blog/
- 文字子字符串(?P<blog_id>\d+)
- 组 "blog_id":1+ 位数/
- 一个/
(?P<slug>[^/]+)
- 组 "slug":/
以外的 1+ 个字符
/?
- 一个可选的/
$
- 字符串结尾。
Here is a regex demo(注意阿拉伯文字中的突出显示字符在那里不起作用。)
Is it the right time to say now I have two problems ...
事实上,您为这项任务选择了正确的工作。
另一个答案似乎有效,但不能容忍其中包含 波斯语 这个词。我发布此答案是为了说明为什么您自己的正则表达式无法按预期工作。
?P<blog_id>[\d+]+
可能您在这里指的是命名组,与您稍后在正则表达式中使用的组相同。您错过了左括号和右括号:(?P<blog_id>[\d+]+)
。另外 [\d+]
表示一个字符 class 由数字和 +
组成。您需要删除 +
:(?P<blog_id>[0-9]+)
(?P<slug>[\X.*]+)
结构很好,但字符 class 不是。 \X
在字符 class 中没有特殊含义,更不用说 Python 甚至不支持它的 re
模块了。 .*
也不例外。在字符中 class 几乎所有特殊标记都按字面意思处理。
所以 [\X.*]
匹配 X
或 .
或星号 *
。您需要将其更改为更通用的内容,例如 [^/]+
,这意味着匹配第一个斜杠(= 匹配除正斜杠之外的任何内容)。