2017-03-22 2 views
0

Hier ther Szenario, würde ich sekundären Pfad in URL extrahieren möge, so dass die folgende URL soll alle return ‚acd‘Regex passend mit Ende Dollarzeichen auf URL-Muster in Python

/opportunity/a-c-d 
/opportunity/a-c-d/ 
/opportunity/a-c-d/123/456/ 
/opportunity/a-c-d/?x=1 
/opportunity/a-c-d?x=1 

Mein Code-Schnipsel ist wie folgt:

m = re.match("^/opportunity/([^/]+)[\?|/|$]", "/opportunity/a-c-d") 
if m: 
    print m.group(1) 

Es funktioniert für alle möglichen URLs oben mit Ausnahme der ersten /opportunity/a-c-d. Kann mir bitte jemand helfen, den Grund zu erklären und meine Regex zu korrigieren? Danke vielmals!

+0

Warum haben Sie '' 'zweimal innerhalb der' [] '? Es gibt keinen Grund, dasselbe Zeichen mehrfach in einem Zeichensatz aufzuführen. – Barmar

+0

Mögliches Duplikat von [Make regex passt dotfiles genau an] (http://stackoverflow.com/questions/42913533/make-regex-match-dotfiles-accurately) –

+0

Ihr regulärer Ausdruck benötigt die zweite Komponente der URL gefolgt von ' ? ',' | ','/'oder' $ '. Keiner von ihnen ist nach "a-c-d" in der ersten URL. – Barmar

Antwort

1

Die $ in Ihrem regex ist passend die wörtlichen Zeichen '$', nicht das Ende der Zeile-Zeichen. Stattdessen möchten Sie dies wahrscheinlich:

m = re.match(r"^/opportunity/([^/?]+)\/?\??", "/opportunity/a-c-d") 
if m: 
    print m.group(1) 
1

Alternative Muster sollten innerhalb (), nicht [] sein, die für die Übereinstimmung bestimmter Zeichen ist.

Sie sollten auch eine rohe Zeichenfolge verwenden, damit Escape-Sequenzen wörtlich an das re-Modul gesendet werden und nicht in der Python-Zeichenfolge interpretiert werden.

m = re.match(r"^/opportunity/([^/]+)(\?|/|$])", "/opportunity/a-c-d") 

oder

m = re.match(r"^/opportunity/([^/]+)([?/]|$])", "/opportunity/a-c-d") 
2

Tun Sie dies nicht. Verwenden Sie stattdessen das Modul urlparse. Hier

ist einiger Testcode:

from urlparse import urlparse 

urls = [ 
    '/opportunity/a-c-d', 
    '/opportunity/a-c-d/', 
    '/opportunity/a-c-d/123/456/', 
    '/opportunity/a-c-d/?x=1', 
    '/opportunity/a-c-d?x=1', 
] 

def secondary(url): 
    try: 
    return urlparse(url).path.split('/')[2] 
    except IndexError: 
    return None 

for url in urls: 
    print '{0:30s} => {1}'.format(url, secondary(url)) 

und hier ist der Ausgang

/opportunity/a-c-d    => a-c-d 
/opportunity/a-c-d/   => a-c-d 
/opportunity/a-c-d/123/456/ => a-c-d 
/opportunity/a-c-d/?x=1  => a-c-d 
/opportunity/a-c-d?x=1   => a-c-d 
+0

Vergiss meine Antwort, das ist richtiger. URL-Parsing ist ein gelöstes Problem, dass Regexes nicht verwendet werden sollten. –

0

Use() enthält alles, was Sie benötigen.

[re.sub(r'.*(\w+-\w+-\w+).*',r'\1',x) for x in urls]