Skip to content

Instantly share code, notes, and snippets.

@guyrt
Created March 3, 2013 16:57
Show Gist options
  • Save guyrt/5076942 to your computer and use it in GitHub Desktop.
Save guyrt/5076942 to your computer and use it in GitHub Desktop.
Match url patterns as regular expressions with named groups.
import re
class NoURLMatchException(Exception):
pass
class URLParser(object):
def __init__(self, regex_definition_handle):
"""
Accepts an iterator of strings that define potential regex URLs.
In django, a way to produce these URLs is as follows:
>> from django.core import urlresolvers
>> resolver = urlresolvers.get_resolver(None)
>> url_re_list = ['^/' + url[1] for url in resolver.reverse_dict.itervalues()]
"""
# Match names fields in python.
# http://regex101.com/r/sJ1wY0
self.re_replace_fields = re.compile(r'\(\?P\<[^\>]+\>[^)]+\)')
# If there is a non-capturing wrapper, it will be eliminated here.
self.re_replace_non_capture = re.compile(r'\(\?\:#/?\)\?')
self.re_replace_wrapped_capture = re.compile(r'\(#\?\/\?\)?\??')
self.re_list = [re.compile(s.strip()) for s in regex_definition_handle]
def parse_url(self, path):
"""
Try regular expressions until one matches.
Return tuple containing all named groups and a URL with fields stripped.
"""
for regex in self.re_list:
match = regex.search(path)
if match:
pattern = self.re_replace_fields.sub('#', regex.pattern)
pattern = self.re_replace_non_capture.sub('#', pattern)
pattern = self.re_replace_wrapped_capture.sub('#', pattern)
return match.groupdict(), pattern
raise NoURLMatchException()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment