2015-11-13 11 views
5

Angenommen, ich habe dieses Stück Text:zu ersetzen, aber das letzte Vorkommen der Zeichenkette in einem Text

Saturday and Sunday and Monday and Tuesday and Wednesday and Thursday and Friday are days of the week. 

Ich möchte alle, aber die letzten and mit einem Komma ersetzt werden:

Saturday, Sunday, Monday, Tuesday, Wednesday, Thursday and Friday are days of the week. 

Gibt es einen einfachen Weg, das in Regex zu tun? Soweit ich weiß, ersetzt die replace Methode in Regex die Zeichenfolgen den ganzen Weg.

+4

Nicht mit dem Oxford Komma, sehe ich. –

+0

Streng genommen tun reguläre Ausdrücke nur Übereinstimmung, und Substitution ist ein Merkmal der Hosting-Sprache, normalerweise seine String-Verarbeitungsmöglichkeiten. – tripleee

+0

Dies ist ein wenig unlesbar. Vielleicht könntest du dich damit amüsieren. ".join (reduzieren (Lambda x, y: x + [" und "+ y] wenn len (x) == 0 sonst x + [", "+ y], re.split (" und "," Samstag und Sonntag und Montag und Dienstag und Mittwoch und Donnerstag und Freitag sind Wochentage. ") [:: - 1], []) [:: - 1]) [1:] –

Antwort

15

str.replace() Methode hat ein count Argument:

str.replace(old, new[, count])

Return eine Kopie des Strings mit allen Vorkommen von Teilzeichen alten durch neue ersetzt. Wenn die Anzahl der optionalen Argumente angegeben wird, werden nur die ersten Zählungen ersetzt.

Dann verwenden str.count() wie viele and in der Zeichenfolge zu überprüfen und dann -1 (weil Sie die letzte and benötigen):

str.count(sub[, start[, end]])

Return die Anzahl der nicht-überlappende Vorkommen von Teilzeichenfolge im Bereich [start, end]. Optionale Argumente Start und Ende werden als Slice-Notation interpretiert.

Demo:

>>> string = 'Saturday and Sunday and Monday and Tuesday and Wednesday and Thursday and Friday are days of the week.' 
>>> string.replace(' and ', ", ", (string.count(' and ')-1)) 
'Saturday, Sunday, Monday, Tuesday, Wednesday, Thursday and Friday are days of the week. ' 
4

Wenn Sie eine regex Lösung wollen, könnten Sie alle and s entsprechen, die von einem anderen gefolgt werden später in der Zeichenkette.

>>> str='Monday and Tuesday and Wednesday and Thursday and Friday and Saturday and Sunday are the days of the week.' 
>>> import re 
>>> re.sub(' and (?=.* and)', ', ', str) 
'Monday, Tuesday, Wednesday, Thursday, Friday, Saturday and Sunday are the days of the week.' 

(?= ... ) ist ein Look-Ahead, die sicher ohne es in dem tatsächlichen Spiel mit (so auch nicht in der Substitution) in der Zeichenfolge später ein Spiel dort macht, ist. Es ist irgendwie wie eine Bedingung für das Spiel.

+0

Was mit dieser Saite passiert:' "Montag und Dienstag und Mittwoch und Donnerstag und Freitag und Samstag und Sonntag sind die Wochentage und es ist Montag." – IanAuld

+0

Das ist leicht zu finden, oder? Vielleicht ändere das '. *' Im Lookahead zu '[^.?!] *', Damit es nie mit der Interpunktion früherer Sätze übereinstimmt. Aber wie gehen Sie dann mit Inter-Satz-Abkürzungen mit einer Periode um, die kein Satzterminator ist? Sie kommen schnell mit [Zawinskis Problem] (http://programmers.stackexchange.com/questions/223634/what-ismeant-by-now-you-have-two-problems). Für alles andere als einfache Token ist Regex wahrscheinlich kein geeignetes Werkzeug. – tripleee

+0

Aber dann für dieses einfache Problem könnten Sie wahrscheinlich noch weiter einschränken, und hoffen, dass es auch nie nach einem Verb passt."John und Mary und ich gingen zum Buckingham Palace und tranken ein Bier." – tripleee

Verwandte Themen