Ну, в настоящее время у вас нет возможности сопоставить %
или &
в вашем регулярном выражении. В зависимости от того, закодирован он или нет, вам нужно добавить один или другой класс символов в вашем регулярном выражении, и он должен совпадать.
Я мог бы изменить его на что-то вроде следующего:
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+)
, но я не хотел менять это в случае, если он намеренно добавляет некоторая дополнительная проверка формата.