Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rebuild regex string based on match keywords in python

Tags:

python

regex

Example regular expression

regex = re.compile('^page/(?P<slug>[-\w]+)/(?P<page_id>[0-9]+)/$')
matches = regex.match('page/slug-name/5/')
>> matches.groupdict()
{'slug': 'slug-name', 'page_id': '5'}

Is there an easy way to pass a dict back to the regex to rebuild a string?

i.e. {'slug': 'new-slug', 'page_id': '6'} would yield page/new-slug/6/

like image 770
dlrust Avatar asked Feb 07 '11 23:02

dlrust


People also ask

How do you replace all occurrences of a regex pattern in a string in Python?

sub() method will replace all pattern occurrences in the target string. By setting the count=1 inside a re. sub() we can replace only the first occurrence of a pattern in the target string with another string. Set the count value to the number of replacements you want to perform.

What is \b in Python regex?

Inside a character range, \b represents the backspace character, for compatibility with Python's string literals. Matches the empty string, but only when it is not at the beginning or end of a word.

How do you check if a string matches a regex pattern in Python?

Use re. match() to check if a string matches a pattern re. match(pattern, string) tests if the regex pattern matches string . Use bool() on the returned match object to return a true or false value.


1 Answers

Regex methods operate on strings. Since you have a dict, I think the string format method is a better fit:

In [16]: d={'slug': 'new-slug', 'page_id': '6'}

In [17]: 'page/{slug}/{page_id}'.format(**d)
Out[17]: 'page/new-slug/6'

There are all sorts of more complicated regex for which the following won't work, but if you always use non-nested named match groups (?P<name>...) and restrict pat to having nothing more complicated than \A, or ^, \Z or $ or \b in your regex pattern otherwise, then perhaps you could do this:

import re
import string


pat=r'\Apage/(?P<slug>[-\w]+)/(?P<page_id>[0-9]+)/\Z'
regex = re.compile(pat)
matches = regex.match('page/slug-name/5/')
print(matches.groupdict())
# {'page_id': '5', 'slug': 'slug-name'}

# Convert '(?P<slug>...)' to '{slug}'    
reverse_pat=re.sub(r'\(\?P<(.*?)>.*?\)',r'{\1}',pat)
# Strip off the beginning ^ and ending $
reverse_pat=re.sub(r'^(?:\\A|\^)(.*)(?:\\Z|\$)$',r'\1',reverse_pat)
# drop any `\b`s.
reverse_pat=re.sub(r'\\b',r'',reverse_pat)
# there are many more such rules one could conceivably need... 
print(reverse_pat.format(**matches.groupdict()))
# page/slug-name/5/
like image 191
unutbu Avatar answered Sep 20 '22 14:09

unutbu