2012-01-09 15 views
18

mam głośny data..something jakPython: usuwanie słów pomiędzy dwoma delimeters

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

teraz chcę tylko, aby wyodrębnić „coś coś” .. Czy istnieje sposób, w jaki sposób usunąć tekst między tymi dwoma ogranicznikami "<" i ">" ??

Dzięki

+0

to zawsze dane tego formularza z jednym wierszem? – vdbuilder

+0

Czy chcesz wyodrębnić "coś na czymś" lub usunąć tekst między ogranicznikami "<" and ">"? –

+0

Cześć ... Dane mają wiele linii. Zasadniczo ogromny plik Chcę wydobyć "coś z czegoś", ale używając re i pięknej zupy ... nagle zostawia mnie z pustym plikiem .. nie do końca pewny dlaczego .. Ale jeśli mogę skasuj tekst między "<" and ">", to też służy temu samemu celowi :) – Fraz

Odpowiedz

34

Zastosowanie regular expressions:

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

[Aktualizacja]

Jeśli próbowałeś wzór jak <.+>, gdzie kropka oznacza dowolny znak, a znak plus oznacza jeden lub więcej, wiem, że to nie działa.

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

Dlaczego!?! Dzieje się tak, ponieważ wyrazy regularne są domyślnie "chciwe". Wyrażenie będzie pasować do wszystkiego, aż do końca łańcucha, w tym do > - a tego nie chcemy. Chcemy dopasować < i zatrzymać się na następnym >, więc używamy wzoru [^x], który oznacza "dowolny znak, ale x" (x jest >).

Operator ? okazuje meczu „non-chciwy”, więc to ten sam efekt:

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

Poprzedniego jest bardziej wyraźny, ten jest mniej pisania; należy pamiętać, że x? oznacza zero lub jedno wystąpienie x.

+0

:) działa jak urok .. dziękuję – Fraz

+4

Jeśli każda odpowiedź regex ZWRÓCIŁ SIĘ, dlaczego regex działa w pierwszej kolejności, tak jak Ty, SO byłby znacznie szczęśliwszym miejscem. +1! – heltonbiker

10

Oczywiście można używać wyrażeń regularnych.

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

Powyższy kod powinien to zrobić.

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

Funkcja re.sub przyjmuje wyrażenie regularne i zastąpić wszystkie mecze w ciągu z drugiego parametru. W tym przypadku wyszukujemy wszystkie znaki między < i > ('<.*?>') i zastępujemy je bez żadnych elementów ('').

Urządzenie ? jest używane w przypadku re w przypadku wyszukiwania nie wymagającego chciwości.

Więcej o re module.


Jeśli że „szumy” są rzeczywiście tagi html, proponuję zajrzeć do BeautifulSoup

1

Tylko zainteresowania, można napisać kod takich jak:

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

Tak, zdecydowałem, że mogą chcieć tego drugiego ">", np. jeśli masz myname-> bob , otrzymasz myname-> bob, w drugiej sytuacji po prostu dostaniesz "Bob". Naprawdę nigdy nie jest idealny do parsowania uszkodzonego xml. Mój kod również się nie powiedzie, jeśli między znacznikami "<" ">" jest nowy znak. Dziękuję za przeczytanie mojego kodu –

3

pierwsze dziękuję Paulo Scardine, użyłem twojego re, aby zrobić coś wspaniałego. Pomysł polegał na tym, aby mieć wolny od znaczników plik po LibreOffice do celów drukowania. Zrobiłem następujący skrypt, który wyczyści plik pomocy dla mniejszych i łatwiejszych.

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() 
Powiązane problemy