2015-04-16 11 views
7

Data una stringa, è necessario sostituire una sottostringa con un'altra in un'area non compresa tra situata tra due parole specificate.Python Regex - sostituire una stringa che non si trova tra due parole specifiche

Ad esempio:

substring: "ate" replace to "drank", 1st word - "wolf", 2nd word - "chicken" 

input: The wolf ate the chicken and ate the rooster 
output: The wolf ate the chicken and drank the rooster 

Attualmente, l'unica soluzione che ho è estremamente impuro

1) Sostituire la stringa situato tra le due parole di una stringa temporanea, tramite Replace a string located between

2) sostituire la stringa che volevo originariamente

3) ripristinare la stringa temporanea sulla stringa originale

Edit:

ho chiesto espressamente una domanda leggermente diversa rispetto al mio caso per mantenere la risposta rilevante per futuri lettori.

Il mio bisogno specifico è dividere una stringa in base a ":", quando ho bisogno di ignorare ":" che sono tra "<" e ">" parentesi che possono essere concatenate, dove l'unica promessa è che il numero di le parentesi d'apertura equivalgono al numero di parentesi di chiusura.

Così, per esempio, nel caso seguente:

input a : <<a : b> c> : <a < a < b : b> : b> : b> : a 
output [a, <<a : b> c>, <a < a < b : b> : b> : b>, a] 

Se le risposte sono molto diversi, inizierò un'altra domanda.

+0

lupo: '{', pollo: ''}, mangiato: 'a'. Sono tutti questi possibili: '" a {a a} a "', '" a {a} a {a} a "', '" {a {a}} "', '" {a} a a "'? Puoi modificare la domanda per spiegare altri casi? – Kobi

+0

sì, specialmente {a {a}}, nel qual caso nessuno di questi "a" deve essere cambiato. – ErezO

+0

In Python, stai usando 're' o' regex'? Hai considerato una soluzione non regex? – Kobi

risposta

1

Utilizzare la funzione re.sub one-liner.

>>> s = "The wolf ate the chicken and ate the rooster" 
>>> re.sub(r'wolf.*?chicken|\bate\b', lambda m: "drank" if m.group()=="ate" else m.group(), s) 
'The wolf ate the chicken and drank the rooster' 

Aggiornamento:

problema Aggiornato sarebbe risolto utilizzando il modulo regex.

>>> s = "a : <<a : b> c> : <a < a < b : b> : b> : b> : a" 
>>> [i for i in regex.split(r'(<(?:(?R)|[^<>])*>)|\s*:\s*', s) if i] 
['a', '<<a : b> c>', '<a < a < b : b> : b> : b>', 'a'] 

DEMO

+0

Il collegamento DEMO non funziona correttamente, l'esempio python allegato funziona perfettamente. – ErezO

+0

sì, mostra solo il testo catturato. Aggiunto solo per mostrare come vengono catturati '<>'. –

+0

Ho trovato un problema: a < b > (no ":") viene diviso in ['a', '< b >']. Non voglio pre-ottimizzare, ma non ho idea di quale sia la prestazione relativa a una soluzione non-regex su misura. – ErezO

3
def repl(match): 
    if match.group()=="ate": 
     return "drank" 
    return match.group() 


x="The wolf ate the chicken and ate the rooster" 
print re.sub(r"(wolf.*chicken)|\bate\b",repl,x) 

È possibile utilizzare una funzione per la sostituzione di fare il trucco con re.sub

+1

Questo è ciò che intendevo :) –

Problemi correlati