vi spiegherò cosa succede con il tuo codice:
import re
file = open('f1.txt')
fixed = open('fnew.txt','w')
text = file.read()
match = re.compile('<.*>')
for unwanted in text:
fixed_doc = match.sub(r' ',text)
fixed.write(fixed_doc)
L'istruzione text = file.read()
crea un oggetto di testo di tipo stringa nome text
.
Nota che uso i caratteri in grassetto text per esprimere un OBJECT e text
per esprimere il nome == IDENTIFIER di questo oggetto.
Come conseguenza dell'istruzione for unwanted in text:
, l'identificatore unwanted
viene successivamente assegnato a ciascun carattere a cui fa riferimento l'oggetto testo.
Inoltre, re.compile('<.*>')
crea un oggetto di tipo RegexObject (che personnaly chiamo compilato) regex o semplicemente regex, <.*>
essendo solo il pattern regex).
Assegnate questo oggetto regex compilato all'identificatore match
: è una pessima pratica, perché match
è già il nome di un metodo di oggetti regex in generale e di quello creato in particolare, quindi è possibile scrivere match.match
senza errore.
match
è anche il nome di una funzione del modulo re.
Questo uso di questo nome per il tuo particolare bisogno è molto confuso. Devi evitarlo.
C'è lo stesso difetto con l'uso di file
come nome per il gestore di file del file f1. file
è già un identificatore utilizzato nella lingua, è necessario evitarlo.
Bene. Ora questo partita oggetto cattivo nome è definito, l'istruzione fixed_doc = match.sub(r' ',text)
sostituisce tutte le occorrenze si trovano in testo con la sostituzione r' '
dal regex partita.
Si noti che è completamente superfluo scrivere r' '
anziché solo ' '
perché non c'è assolutamente nulla in ' '
che deve essere sfuggito. È un maniaco di alcune persone ansiose scrivere stringhe non elaborate ogni volta che devono scrivere una stringa in un problema di regex.
A causa del suo modello <.+>
in cui il simbolo del punto significa "avidamente mangiare ogni carattere situato tra un <
e >
tranne se si tratta di un carattere di nuova riga", le occorrenze catched nel testo da partita sono ogni linea fino a quando l'ultimo >
in esso.
Poiché il nome unwanted
non viene visualizzato in questa istruzione, è la stessa operazione eseguita per ciascun carattere del testo, uno dopo l'altro. Vale a dire: niente di interessante.
Per analizzare l'esecuzione di un programma, è necessario inserire alcune istruzioni di stampa nel codice, consentendo di capire cosa succede.Ad esempio, se fai print repr(fixed_doc)
, vedrai la stampa ripetuta di questo: ' \n \n \n '
. Come ho detto: niente di interessante.
C'è un altro valore predefinito nel codice: si aprono i file, ma non li si chiude. È obbligatorio chiudere i file, altrimenti potrebbe accadere qualche strano fenomeno, che personalmente ho osservato in alcuni dei miei codici prima di rendermi conto di questo bisogno. Alcune persone fingono che non sia obbligatorio, ma è falso.
A proposito, il modo migliore per aprire e chiudere i file consiste nell'utilizzare l'istruzione with
. Fa tutto il lavoro senza che tu ti debba preoccupare.
.
Così, ora posso proporre un codice per il primo problema:
import re
def ripl(mat=None,li = []):
if mat==None:
li[:] = []
return
if mat.group(1):
li.append(mat.span(2))
return ''
elif mat.span() in li:
return ''
else:
return mat.group()
r = re.compile('</[^>]+>'
'|'
'<([^>]+)>(?=.*?(</\\1>))',
re.DOTALL)
text = '''<something @37>
<name>George <wxc>Washington</name>
<a23c>Joe </zazaza>Taylor</a23c>
</something @37>'''
print '1------------------------------------1'
print text
print '2------------------------------------2'
ripl()
print r.sub(ripl,text)
print '3------------------------------------3'
risultato
1------------------------------------1
<something @37>
<name>George <wxc>Washington</name>
<a23c>Joe </zazaza>Taylor</a23c>
</something @37>
2------------------------------------2
George <wxc>Washington
Joe </zazaza>Taylor
3------------------------------------3
Il principio è il seguente:
Quando l'espressione regolare rileva un tag,
- se è un tag di chiusura, corrisponde a - se è un tag di inizio, corrisponde solo se c'è un tag di chiusura corrispondente da qualche parte ulteriormente nel testo
Per ciascuna corrispondenza, il metodo sub()
della regex r
chiama la funzione ripl()
per eseguire la sostituzione.
Se la corrispondenza è con un tag di inizio (che è necessario seguito da qualche parte nel testo dal suo tag di chiusura corrispondente, per costruzione della regex), quindi ripl()
restituisce ''
.
Se la corrispondenza è con un tag di chiusura, ripl()
restituisce ''
solo se questo tag di fine è stato rilevato in precedenza nel testo è il tag di fine corrispondente di un tag di inizio precedente. Ciò è possibile effettuando la registrazione in un elenco li l'intervallo di span di ciascun tag finale corrispondente ogni volta che viene rilevato un tag di avvio e corrispondente.
La lista di registrazione li è definito come un argomento di default in modo che sia sempre la stessa lista che viene utilizzato a ogni chiamata della funzione ripl()
(si prega, si riferiscono alla functionning di argomento di default per undertsand, perché è sottile).
Come conseguenza della definizione di li
come parametro che riceve un argomento predefinito, l'oggetto elenco li conserva tutti gli span registrati durante l'analisi di più testo nel caso in cui più testi vengano analizzati successivamente. Per evitare che l'elenco li conservi gli span delle corrispondenze di testo passate, è necessario rendere l'elenco vuoto. Ho scritto la funzione in modo che il primo parametro sia definito con un argomento predefinito None
: che consente di chiamare ripl()
senza argomento prima di utilizzarlo nel metodo sub()
di un'ergere.
Quindi, si deve pensare di scrivere ripl()
prima di utilizzarlo.
.
Se si desidera rimuovere i ritorni a capo del testo al fine di ottenere il risultato preciso hai mostrato nella sua interrogazione, il codice deve essere modificato per:
import re
def ripl(mat=None,li = []):
if mat==None:
li[:] = []
return
if mat.group(1):
return ''
elif mat.group(2):
li.append(mat.span(3))
return ''
elif mat.span() in li:
return ''
else:
return mat.group()
r = re.compile('(*\n *)'
'|'
'</[^>]+>'
'|'
'<([^>]+)>(?=.*?(</\\2>)) *',
re.DOTALL)
text = '''<something @37>
<name>George <wxc>Washington</name>
<a23c>Joe </zazaza>Taylor</a23c>
</something @37>'''
print '1------------------------------------1'
print text
print '2------------------------------------2'
ripl()
print r.sub(ripl,text)
print '3------------------------------------3'
risultato
1------------------------------------1
<something @37>
<name>George <wxc>Washington</name>
<a23c>Joe </zazaza>Taylor</a23c>
</something @37>
2------------------------------------2
George <wxc>WashingtonJoe </zazaza>Taylor
3------------------------------------3
Ciao. Nel primo problema, è tua intenzione eliminare TUTTI quelli che assomigliano a tag o tag che definiscono veramente un elemento di un linguaggio di markup? Uso la parola "elemento" nel suo giusto e corretto significato, ovvero "tag di inizio + contenuto di elementi + tag di fine". - Inoltre, man mano che esponi il contenuto del file f, ci sono delle righe, vale a dire delle newline. Quello che mostri come risultato desiderato è una stringa in cui non ci sono più righe nuove. E 'davvero quello che vuoi o ti piacerebbe mantenere la struttura in linea? – eyquem
Cosa vorresti dire con '' se valore non in []) ''? Attualmente non ha senso, dal momento che non c'è sempre nulla in una lista di nulla. Cosa desideri fare come confronto dei file? Non è molto chiaro – eyquem