2016-08-02 6 views
0

Ich schaffe einen regulären Ausdruck Urls zu finden wie /places/:state/:city/whatevermit re.sub in Python

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

Dies funktioniert gut:

import re 

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

Drucke {'city': 'NY', 'state': 'NY'}.

Wie kann ich eine Logdatei verarbeiten, um /places/NY/NY/other/stuff durch die Zeichenfolge "/places/:state/:city/other/stuff" zu ersetzen? Ich würde gerne ein Gefühl dafür bekommen, wie viele URLs vom "Städte-Typ" sind, ohne sich darum zu kümmern, dass die Orte (NY, NY) spezifisch sind.

kann Der einfache Ansatz scheitern:

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 gedruckt wird, die rückwärts!

Fühlt sich an, als sollte es eine Möglichkeit geben, re.sub zu verwenden, aber ich kann es nicht sehen.

+1

Sie die dict sortiert haben, so 'city' kommt vor' Zustand 'während der Ersetzung –

+0

@MosesKoledoye ist der Wert von' groupdict() 'garantiert in der gleichen Reihenfolge wie die Übereinstimmungen sortiert (oder eine bestimmte Reihenfolge überhaupt)? Es scheint nur ein eingebautes '' zu sein. –

+2

Ja, es ist mehr oder weniger das eingebaute Diktat. Die Reihenfolge der Elemente im Diktat entspricht nicht der Reihenfolge der Übereinstimmungen. –

Antwort

0

Es wurde ein besserer Weg gefunden, dies zu tun. Es ist eine Eigenschaft groupindex auf einem kompilierten regulären Ausdruck, der die Gruppen druckt und ihre Aufträge in der Musterkette:

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

, die leicht in der richtigen Reihenfolge durchlaufen werden können:

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

Mit diesem , Sollte ich garantieren können, dass ich die Übereinstimmungen in ihrer richtigen Reihenfolge von links nach rechts ersetze:

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 

Diese Schleifen über die Gruppen in der richtigen Reihenfolge, die dafür sorgt, dass der Ersatz auch in der richtigen Reihenfolge auftritt, zuverlässig in der richtigen Zeichenfolge resultierenden:

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