2016-10-25 4 views
2

Ich versuche, das letzte Vorkommen einer Teilzeichenkette aus einer Zeichenkette zu ersetzen, indem ich re in Python benutze, aber mit dem Regex-Muster festhalte. Kann mir jemand helfen, das richtige Muster zu bekommen?re() - Regex zum Ersetzen des letzten Auftretens einer Teilzeichenkette in einer Zeichenkette

String = "cr US TRUMP DE NIRO 20161008cr_x080b.wmv" 

oder

String = "crcrUS TRUMP DE NIRO 20161008cr.xml"

Ich möchte das letzte Vorkommen von "cr" und alles, was vor der Erweiterung ersetzen.

gewünschte Ausgang Saiten -

"cr US TRUMP DE NIRO 20161008.wmv" 
"crcrUS TRUMP DE NIRO 20161008.xml" 

ich re.sub bin mit, sie zu ersetzen.

re.sub('pattern', '', String) 

Bitte beraten.

+0

'muster' ist dein muster? naja, das geht natürlich nicht ... –

+0

Bitte zeigen Sie das tatsächliche Muster und die Zeichenfolge, die Sie verwenden. – cco

+0

['cr (?!. * Cr) [^.] *'] (Https://regex101.com/r/CL0VOT/1) –

Antwort

4

einen gierigen Quantor und eine Capture-Gruppe mit:

re.sub(r'(.*)cr[^.]*', '\\1', input) 
+0

Dies ist ordentlich, aber wird nicht funktionieren, wenn die Eingabe ist 'acr.crt' – anubhava

+0

@anubhava: Es gibt mehrere Fälle, in denen dieses Muster nicht funktioniert, Sie können auch einen Dateinamen mit mehreren Punkten betrachten. Es ist offensichtlich kein wasserdichtes Muster, es ist mehr eine einfache Illustration, wie man das letzte Vorkommen mit der Gier erreichen kann. Sobald Sie die Idee haben, können Sie sie für einen bestimmten Anwendungsfall verbessern. –

1

Sie können diese negative Vorschau regex verwenden:

repl = re.sub(r"cr((?!cr)[^.])*(?=\.[^.]+$)", "", input); 

RegEx Demo

RegEx Breakup:

cr   # match cr 
(?:  # non-capturing group start 
    (?!  # negative lookahead start 
     cr # match cr 
    )  # negative lookahead end 
    [^.] # match anything but DOT 
)   # non-capturing group end 
*   # match 0 or more of matching character that doesn't have cr at next postion 
(?=  # positive lookahead start 
    \.  # match DOT 
    [^.]+ # followed by 1 or more anything but DOT 
    $  # end of input 
)   # postive lookahead end 
4

Die alternative Lösung str.rfind(sub[, start[, end]]) Funktion:

string = "cr US TRUMP DE NIRO 20161008cr_x080b.wmv" 
last_position = string.rfind('cr') 
string = string[:last_position] + string[string.rfind('.'):] 

print(string) #cr US TRUMP DE NIRO 20161008.wmv 

Außerdem rfind wird viel schneller in einem solchen Fall gehen:
hier Messergebnisse:
mit str.rfind(...): 0,0054836273193359375
mit re.sub(...)              : 0.4017353057861328

+2

Beste Option imo. Es hat keinen Sinn, Regexs zu verwenden, wenn sie nicht benötigt werden. Es ist schon fraglich, ob es gut ist, wenn sie benötigt werden ... – spectras

+0

@spectras, ja, natürlich. Außerdem funktioniert es in solchen Fällen viel schneller – RomanPerekhrest

Verwandte Themen