Регулярное выражение, использующее условное "ИЛИ" - PullRequest
2 голосов
/ 09 октября 2008

Я мог бы помочь с написанием регулярного выражения. В моем приложении Django пользователи могут перейти по следующему URL:

http://www.example.com/A1/B2/C3

Я хотел бы создать регулярное выражение, которое позволяет принимать любое из следующего в качестве действительного URL:

http://www.example.com/A1  
http://www.example.com/A1/B2  
http://www.example.com/A1/B2/C3  

Полагаю, мне нужно использовать условное "ИЛИ", но у меня возникают проблемы с проверкой моего регулярного выражения. Есть мысли?

ОБНОВЛЕНИЕ : Здесь приведено регулярное выражение. Обратите внимание, что я не включил часть "http://www.example.com" - Django обрабатывает это для меня. Я просто заинтересован в проверке 1,2 или 3 подкаталогов.

^(\w{1,20})|((\w{1,20})/(\w{1,20}))|((\w{1,20})/(\w{1,20})/(\w{1,20}))$

Ответы [ 6 ]

5 голосов
/ 09 октября 2008

Пропустить |, использовать ? и ()

http://www\.example\.com/A1(/B2(/C3)?)?

А если заменить А1-С3 на рисунок:

http://www\.example\.com/[^/]*(/[^/]*(/[^/]*)?)?

Пояснение:

  • соответствует каждой строке, которая начинается с http://www.example.com/A1
  • может соответствовать дополнительному /B2 и даже дополнительному /C3, но /C3 сопоставляется только при наличии /B2
  • [^/]* (как можно больше не косых черт)
  • если вам нужен A1-C3 в специальных группах захвата, вы можете использовать это:

http://www\.example\.com/([^/]*)(/([^/]*)(/([^/]*))?)?

Даст (groupnumber: content):

matches: 0: (http://www.example.com/dir1/dir2/dir3)
1: (dir1)
2: (/dir2/dir3)
3: (dir2)
4: (/dir3)
5: (dir3)

Вы можете проверить это онлайн здесь или получить этот инструмент (да, это бесплатно, и даже написано на Лиспе ...).

3 голосов
/ 22 июля 2009

Существует гораздо больше способов сделать это с помощью Django:

urlpatterns = patterns('',
    url(r'^(?P<object_slug1>\w{2}/(?P<object_slug2>\w{2}/(?P<object_slug3>\w{2})$', direct_to_template, {"template": "two_levels_deep.html"}, name="two_deep"),
    url(r'^(?P<object_slug1>\w{2}/(?P<object_slug2>\w{2})$', direct_to_template, {"template": "one_level_deep.html"}, name="one_deep"),
    url(r'^(?P<object_slug1>\w{2})$', direct_to_template, {"template": "homepage.html"}, name="home"),
)

Другие методы не используют возможности Django для передачи переменных.

Edit: я изменил порядок urlpattern, чтобы он был более очевидным для синтаксического анализатора (то есть снизу вверх более определен, чем сверху вниз).

1 голос
/ 15 октября 2008

Помните, что обратный URL-адрес Django (постоянные ссылки, reverse() и {% url %}) может обрабатывать ограниченное подмножество регулярных выражений. Чтобы иметь возможность их использовать, иногда необходимо разделить сложные регулярные выражения на отдельные правила диспетчера URL.

1 голос
/ 09 октября 2008

Если я понимаю, я думаю, вам просто нужен еще один набор скобок вокруг всего выражения ИЛИ:

^((\w{1,20})|((\w{1,20})/(\w{1,20}))|((\w{1,20})/(\w{1,20})/(\w{1,20})))$
1 голос
/ 09 октября 2008
 ^(\w{1,20})(/\w{1,20})*

это для любого количества подкаталогов, если вам нужно только 2:

 ^(\w{1,20})(/\w{1,20}){0,2}
1 голос
/ 09 октября 2008
http://www\.example\.com/A1(/B2(/C3)?)?
...