2015-11-13 11 views
5

Supponiamo che io ho questo pezzo di testo:Per sostituire, ma l'ultima occorrenza di stringa in un testo

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

voglio tutti, ma l'ultimo and da sostituire con una virgola:

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

C'è un modo semplice per farlo in regex? Per quanto ne so, il metodo replace in regex sostituisce completamente le stringhe.

metodo
+4

Non usare la virgola Oxford, vedo. –

+0

In senso stretto, le espressioni regolari fanno solo corrispondenze e la sostituzione è una caratteristica della lingua di hosting, di solito le sue strutture di elaborazione delle stringhe. – tripleee

+0

Questo è un po 'illeggibile. Forse potresti divertirti con esso. "" .join (riduci (lambda x, y: x + ["e" + y] se len (x) == 0 altro x + ["," + y], re.split ("e", "sabato e domenica e lunedì e martedì e mercoledì e giovedì e venerdì sono giorni della settimana. ") [:: - 1], []) [:: - 1]) [1:] –

risposta

15

str.replace() ha un argomento count:

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

restituire una copia della stringa con tutte le occorrenze della stringa old sostituite da nuove. Se viene fornito il conteggio degli argomenti facoltativo, vengono sostituite solo le occorrenze del primo conteggio.

Quindi, utilizzare str.count() per verificare quante and nella stringa e poi -1 (perché è necessario l'ultimo and):

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

ritorno il numero di occorrenze non sovrapposte di sottostringa secondaria nell'intervallo [start, end]. Gli argomenti opzionali start e end sono interpretati come nella notazione slice.

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

Se si desidera una soluzione regex, si potrebbe abbinare tutte le and s che sono seguiti da un altro più avanti nella stringa.

>>> 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.' 

(?= ... ) è un lookahead che assicura c'è una corrispondenza nella stringa senza includere nella partita reale (quindi anche non in sostituzione). È un po 'come un condizionale alla partita.

+0

Cosa accadrà a questa stringa:' 'Lunedì e martedì e mercoledì e giovedì e venerdì e sabato e domenica sono i giorni della settimana ed è lunedì. – IanAuld

+0

È facile da scoprire, vero? Forse cambiate '. *' Nel lookahead a '[^.?!] *' Per non permettere mai che corrisponda alla punteggiatura della frase precedente. Ma come gestisci le abbreviazioni inter-frase con un periodo che non è un terminatore di frase? Stai per finire con [il problema di Zawinski] (http://programmers.stackexchange.com/questions/223634/che-è-spiega-di-ora-dai-due-problemi). Per qualcosa che va oltre i semplici token, la regex non è probabilmente uno strumento adatto. – tripleee

+0

Ma allora per questo semplice problema potresti probabilmente limitarlo ancora di più, e spero che non corrisponda mai a un verbo."John e Mary e io siamo andati a Buckingham Palace e abbiamo preso una birra." – tripleee

Problemi correlati