简体   繁体   中英

Python regular expressions replacing

I have always had hard time understanding regular expressions. With the help of web searches i have always managed to pull through somehow. Guess i have never bothered to really learn then. Sorry.

But i need help with them yet again.

I have a dict like

d = {'account_id':a_value,'group_id':g_value,'other_id':o_value }

And i have bunch of strings like:

s1 = r'^settings/usergroups/(?P<group_id>\d+)/cargroups/$'
s2 = r'^settings/usergroups/(?P<group_id>\d+)/other/(?P<other_id>\d+)/$',
s3 = r'^settings/account/(?P<account_id>\d+)/other/(?P<other_id>\d+)/$',

How can O replace the (?P< group_id >\\d+) , (?P< account_id >\\d+) , (?P< other_id >\\d+) in the strings with matching values from dict?

Regular expressions can contain nested parentheses.

However, Python regular expressions can not match strings containing arbitrarily deep nested parentheses in a way that respects the nested structure. (It is possible using Perl's recursive regular expressions.)

So, if your use case involves strings that DO NOT contain nested paretheses, then the following suffices, but note carefully the undesired extra parenthesis in the last result below:

import re
d = {'account_id':'a_value','group_id':'g_value','other_id':'o_value' }

tests = (r'^settings/usergroups/(?P<group_id>\d+)/cargroups/$',
         r'^settings/usergroups/(?P<group_id>\d+)/other/(?P<other_id>\d+)/$',
         r'^settings/account/(?P<account_id>\d+)/other/(?P<other_id>\d+)/$',
         r'^settings/usergroups/(?P<group_id>(\d+|\w))/other/(?P<other_id>\d+)/$'
         )
metapat = r'\(\?P<(.*?)>.*?\)'
for t in tests:
      result = re.sub(metapat, r'{\1}', t)
      if result:
            print(result.format(**d))

yields

^settings/usergroups/g_value/cargroups/$
^settings/usergroups/g_value/other/o_value/$
^settings/account/a_value/other/o_value/$
^settings/usergroups/g_value)/other/o_value/$

If you do need to parse nested parentheses, then you'll need a different parser than re . Pyparsing , for example, can handle nested expressions.

If you want to go with simple string modifications and just replace the strings by their value associated in d , you can do this:

for key in d:
    s = s.replace(key,str(d[key]))
s = s.replace('(?P<','').replace('>\d+)','')

This problem is not related to regular expressions; but more of generating URLs for a particular view.

First, to make your life easy and name your url patterns :

urlpatterns = patterns('',
    (r'^settings/usergroups/(?P<group_id>\d+)/cargroups/$', 'car_groups_by_id'),
    # and so on
)

Then in your views.py , if you want to redirect a user:

from django.shortcuts import redirect

def foo(request):
    return redirect('car_groups_by_id',group_id=1234)

If you want to generate the url in your templates:

{% url 'car_groups_by_id' group_id=1234 %}

If you just want to print the URL:

>>> from django.core.urlresolvers import reverse
>>> reverse('car_groups_by_id',kwargs={'group_id': 1234})

The generic, non-django way of doing this would be to use the built in template strings :

>>> from string import Template
>>> t = Template('foo/bar/$group_id/zoo/')
>>> t.substitute(group_id=1234)
'foo/bar/1234/zoo/'

In either case, this is not a regular expression problem since you are not trying to match something - simply replace tokens in strings. It just so happens that your example string's tokens are python regular expressions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM