2012-01-09 19 views
18

ho un data..something rumoroso comePython: eliminare le parole tra i due delimitatori

<@ """@$ FSDF >something something <more noise> 

ora voglio solo estrarre "qualcosa di qualcosa" .. C'è un modo su come eliminare il testo tra questi due delimitatori "<" e ">" ??

Grazie

+0

sono i dati sempre di quella forma con uno per riga? – vdbuilder

+0

Vuoi estrarre "qualcosa di" o eliminare il testo tra i delimitatori "<" and ">"? –

+0

Ciao .. I dati hanno più righe ... in sostanza un enorme file Voglio estrarre "qualcosa di" ma usando re e una bella zuppa .. improvvisamente mi lascia con un file vuoto .. non del tutto sicuro del perché .. Ma se posso cancella il testo tra "<" and ">", che ha anche lo stesso scopo :) – Fraz

risposta

34

Uso regular expressions:

>>> import re 
>>> s = '<@ """@$ FSDF >something something <more noise>' 
>>> re.sub('<[^>]+>', '', s) 
'something something ' 

[Update]

Se si è tentato un modello come <.+>, dove il punto: ogni personaggio e il segno più: uno o più, si sapere che non funziona

>>> re.sub(r'<.+>', s, '') 
'' 

Perché!?! Succede perché le espressioni regolari sono "golose" per impostazione predefinita. L'espressione corrisponderà a qualsiasi cosa fino alla fine della stringa, incluso lo >, e questo non è ciò che vogliamo. Vogliamo corrispondere allo < e fermarci al prossimo >, quindi utilizziamo il modello [^x] che significa "qualsiasi carattere tranne x" (x è >).

L'operatore ? trasforma la partita "non-greedy", quindi questo ha lo stesso effetto:

>>> re.sub(r'<.+?>', '', s) 
'something something ' 

Il precedente è più esplicito, questo è meno digitando; essere consapevoli del fatto che x? significa zero o una ricorrenza di x.

+0

:) funziona come un incantesimo .. grazie – Fraz

+4

Se ogni regex risponde SPIEGATO perché la regex funziona in primo luogo, come hai fatto tu, SO sarebbe un posto molto più felice. +1! – heltonbiker

10

Naturalmente, è possibile utilizzare le espressioni regolari.

import re 
s = #your string here 
t = re.sub('<.*?>', '', s) 

Il codice sopra dovrebbe farlo.

3
import re 
my_str = '<@ """@$ FSDF >something something <more noise>' 
re.sub('<.*?>', '', my_str) 
'something something ' 

La funzione re.sub prende un expresion regolare e sostituire tutte le partite nella stringa con il secondo parametro. In questo caso, cerchiamo tutti i caratteri compresi tra < e > ('<.*?>') e li sostituiamo con nulla ('').

? viene utilizzato in re per ricerche non ingenue.

Ulteriori informazioni su re module.


se quel "rumori" sono in realtà tag html, vi suggerisco di guardare in BeautifulSoup

1

Solo per interessi, si potrebbe scrivere del codice come ad esempio:

with open('blah.txt','w') as f: 
    f.write("""<sdgsa>one<as<>asfd<asdf> 
<asdf>two<asjkdgai><iasj>three<fasdlojk>""") 

def filter_line(line): 
    count=0 
    ignore=False 
    result=[] 
    for c in line: 
     if c==">" and count==1: 
      count=0 
      ignore=False 
     if not ignore: 
      result.append(c) 
     if c=="<" and count==0: 
      ignore=True 
      count=1 
    return "".join(result) 

with open('blah.txt') as f: 
    print "".join(map(filter_line,f.readlines())) 

>>> 
<>one<>asfd<> 
<>two<><>three<> 
+0

Sì, ho deciso che potrebbero volere quel secondo ">", ad es. se hai myname-> bob , si otterrebbe myname-> bob, nell'altra situazione si otterrebbe 'bob'. Non è davvero mai l'ideale per analizzare xml rotti. Il mio codice fallisce anche se c'è un nuovo carattere di linea tra i tag "<" ">". Grazie per aver letto il mio codice però –

3

primo ringraziamento Paulo Scardine, ho usato il tuo re per fare grandi cose. L'idea era di avere un file lib LibreOffice senza tag per scopi di stampa. E ho fatto il seguente script che pulirà il file di aiuto per quelli più piccoli e più facili.

import re 
f = open('a.csv') 
text = f.read() 
f.close() 

clean = re.sub('<[^>]+>', ' ', text) 

f = open('b.csv', 'w') 
f.write(clean) 
f.close() 
Problemi correlati