Regex в Django для URL с% или & - PullRequest
       1

Regex в Django для URL с% или &

0 голосов
/ 03 февраля 2012

У меня есть URL, который будет united-states/boulder-21781/tool-&-anchor/mulligan-21/. Предполагая, что лучшая стратегия заключается в кодировании &, URL изменяется на united-states/boulder-21781/tool-%26-anchor/mulligan-21/

Я пытаюсь написать url conf, который примет это, но регулярное выражение, которое я использую, не работает. У меня есть:

    url(r'^%(regex)s/%(regex)s-(\d+)/%(regex)s/%(regex)s-(\d+)/$' % {'regex'= '(?i)([\.\-\_\w]+)'}, 'view_tip_page', name='tip_page'),

Что мне добавить, чтобы захватить%? или я должен просто включить &?

Ответы [ 2 ]

1 голос
/ 03 февраля 2012

Моя первая рекомендация - не делать этого. Как вы сами демонстрируете, не все знают, что & является совершенно допустимым символом в URI перед первым ?, и вы неизбежно столкнетесь с проблемами. Это также выглядит некрасиво, его сложнее набрать, и оно более резкое, чем, скажем, and или даже просто n. Сказав это, если вы действительно хотите это там, просто поместите это туда в классе персонажей.

Не имеет отношения к вашему вопросу, то, как вы строите это регулярное выражение, странно; Вы не захватываете какие-либо части пути для использования представлением. Вы также включаете глобальный модификатор (?i) четыре раза и указываете _, который уже является частью \w. Я не знаю, я ожидал бы что-то вроде

r'(?i)(?P<country>[.\w-]+)/(?P<city>[.\w-]+)-(?P<cityno>[\d+])/...etc...

но, может быть, я что-то упустил.

0 голосов
/ 03 февраля 2012

Ну, в настоящее время у вас нет возможности сопоставить % или & в вашем регулярном выражении. В зависимости от того, закодирован он или нет, вам нужно добавить один или другой класс символов в вашем регулярном выражении, и он должен совпадать.

Я мог бы изменить его на что-то вроде следующего:

r'(?i)^%(regex)s/%(regex)s-(\d+)/%(regex)s/%(regex)s-(\d+)/$' % {'regex': r'([-.%\w]+)'}

И доказательство того, что это работает:

>>> pattern = re.compile(r'(?i)^%(regex)s/%(regex)s-(\d+)/%(regex)s/%(regex)s-(\d+)/$' % {'regex': r'([-.%\w]+)'})
>>> s = 'united-states/boulder-21781/tool-%26-anchor/mulligan-21/'
>>> match = pattern.match(s)
>>> match.groups()
('united-states', 'boulder', '21781', 'tool-%26-anchor', 'mulligan', '21')

Несколько комментариев к вашему регулярному выражению:

(?i) на самом деле ничего не делает, так как вы используете \w, который уже будет соответствовать как верхнему, так и нижнему регистру. Если вы хотите использовать (?i), я бы переместил его из строки замены в строку формата ('(?i)...' % {'regex': '...'} вместо '...' % {'regex': '(?i)...'}), так как в противном случае он будет отображаться несколько раз.

Обратите внимание, что класс символов был изменен с [\.\-\_\w] на [-.%\w], это потому, что подчеркивания включены в \w, вам не нужно экранировать дефис, если он появляется в начале класса символов, и вам не нужно экранировать . внутри классов символов.

Кроме того, \w сопоставляет цифры так технически, чтобы соответствовать чему-то вроде 'boulder-21781', вы можете просто использовать %(regex)s вместо %(regex)s-(\d+), но я не хотел менять это в случае, если он намеренно добавляет некоторая дополнительная проверка формата.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...