2016-08-02 31 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