2016-08-02 124 views
0

我创建了一个正则表达式找到的网址像/places/:state/:city/whatever与应用re.sub替换特定的命名组在python

p = re.compile('^/places/(?P<state>[^/]+)/(?P<city>[^/]+).*$') 

这只是正常:

import re 

p = re.compile('^/places/(?P<state>[^/]+)/(?P<city>[^/]+).*$') 
path = '/places/NY/NY/other/stuff' 
match = p.match(path) 
print match.groupdict() 

打印{'city': 'NY', 'state': 'NY'}

如何处理日志文件以用字符串"/places/:state/:city/other/stuff"替换/places/NY/NY/other/stuff?我希望了解有多少网址属于“城市类型”,而不必关心具体的地点(NYNY)。

简单的方法可能会失败:

import re 

p = re.compile('^/places/(?P<state>[^/]+)/(?P<city>[^/]+).*$') 
path = '/places/NY/NY/other/stuff' 
match = p.match(path) 
if match: 
    groupdict = match.groupdict() 
    for k, v in sorted(groupdict.items()): 
    path = path.replace(v, ':' + k, 1) 
print path 

将打印/places/:city/:state/other/stuff,这是倒退!

感觉应该有一些使用方法re.sub但我看不到它。

+1

你排序的字典,所以'city'到来之前'状态'在替换期间 –

+0

@MosesKoledoye是'groupdict()'返回的值,保证按照与匹配相同的顺序排序(或者任何特定顺序)?它似乎只是一个内置的''。 –

+2

是的,这或多或少是内建“字典”。字典中的项目排序不会反映匹配的顺序。 –

回答

0

想出了一个更好的方法来做到这一点。有一个属性groupindex在编译的正则表达式,打印模式字符串组和他们的订单

>>> p = re.compile('^/places/(?P<state>[^/]+)/(?P<city>[^/]+).*$') 
>>> p.groupindex 
{'city': 2, 'state': 1} 

它可以很容易按照正确的顺序进行迭代:

>>> sorted(p.groupindex.items(), key=lambda x: x[1]) 
[('state', 1), ('city', 2)] 

使用此,我应该能够保证我以正确的从左到右顺序替换匹配:

p = re.compile('^/places/(?P<state>[^/]+)/(?P<city>[^/]+).*$') 
path = '/places/NY/NY/other/stuff' 
match = p.match(path) 
if match: 
    groupdict = match.groupdict() 
    for k, _ in sorted(p.groupindex.items(), key=lambda x: x[1]): 
     path = path.replace(groupdict[k], ':' + k, 1) 
print path 

这遍历以正确的顺序组,这就保证了更换也发生在正确的顺序,可靠地产生正确的字符串:

/places/:state/:city/other/stuff