2012-05-07 21 views
7

Widziałem wiele pytań na temat usuwania znaczników HTML z ciągów, ale wciąż nie jestem pewien, jak należy postępować z moją konkretną sprawą.Usuwanie znaczników graficznych html i wszystkich pośrednich z ciągu

Widziałem, że wiele postów odradza używanie wyrażeń regularnych do obsługi HTML, ale podejrzewam, że mój przypadek uzasadnia rozważne obejście tej zasady.

Próbuję parsować pliki PDF i udało mi się przekonwertować każdą stronę z mojego przykładowego pliku PDF na ciąg tekstu UTF-32. Gdy pojawiają się obrazy, wstawiany jest znacznik w stylu HTML, który zawiera nazwę i lokalizację obrazu (który jest zapisany w innym miejscu).

W oddzielnej części mojej aplikacji muszę pozbyć się tych tagów graficznych. Ponieważ jesteśmy tylko zajmujących się tagami obrazu, podejrzewam, że korzystanie z regex może być uzasadnione.

Moje pytanie jest dwojaki:

  1. powinienem użyć wyrażenia regularnego, aby usunąć te tagi, czy mam nadal korzystać z modułu parsowania HTML, takich jak BeautifulSoup?
  2. Których konstrukcji regex lub BeautifulSoup powinienem użyć? Innymi słowy, jak mam to zakodować?

Dla jasności, znaczniki są skonstruowane jako <img src="/path/to/file"/>

Dzięki!

+0

Czy istnieje inny plik HTML w tym pliku? Czy jest to dosłownie tylko zwykły tekst i znaczniki '? – senderle

+0

@senderle Nie, nie ma kodu HTML poza tagami , stąd moje wahanie w używaniu pełnowartościowej biblioteki HTML. Format jest * zawsze * jak opisuję to powyżej. – blz

+0

Właśnie napisałem odpowiedź, ale zastanawiałem się, czy rzeczywiście istnieje apostrof po zamknięciu> każdego obrazu, czy też był to literówka? – joshcartme

Odpowiedz

8

Głosowałbym, że w twoim przypadku dopuszczalne jest użycie wyrażenia regularnego. Coś jak to powinno działać:

def remove_html_tags(data): 
    p = re.compile(r'<.*?>') 
    return p.sub('', data) 

Znalazłem ten fragment tutaj (http://love-python.blogspot.com/2008/07/strip-html-tags-using-python.html)

edit: wersja która usunie tylko rzeczy formularza <img .... />:

def remove_img_tags(data): 
    p = re.compile(r'<img.*?/>') 
    return p.sub('', data) 
+0

Widziałem tę stronę wcześniej, ale jestem nieco zdezorientowany w związku z tym regexem (proszę zauważyć, że wiem * nic * o regexie posługiwać się). Dlaczego ciąg '. *?'? Czy nie powinien przeczytać czegoś takiego jak ''? – blz

+1

Sposób, w jaki opublikowałem pierwszy, polegał na usunięciu wszystkiego między < and >. Gdybyś miał inne wystąpienia w postaci zwykłego tekstu (nie jako znaczników html), musiałby usunąć rzeczy, których nie powinien mieć. Właśnie opublikowałem kolejną wersję, która jest nieco bardziej selektywna. – joshcartme

+0

Super! Dziękuję bardzo! – blz

3

Ponieważ tekst ten zawiera tylko tagów graficznych, to chyba OK, aby użyć wyrażenia regularnego. Ale na cokolwiek innego prawdopodobnie lepiej użyć parabolu HTML. Na szczęście Python zapewnia jeden! Jest to całkiem niezgrabne - aby było w pełni funkcjonalne, musiałoby obsługiwać znacznie więcej narożnych przypadków. (. Przede wszystkim, XHTML-style pustych tagów (kończący się ukośnikiem <... />) nie są prawidłowo obsługiwane tutaj)

>>> from HTMLParser import HTMLParser 
>>> 
>>> class TagDropper(HTMLParser): 
...  def __init__(self, tags_to_drop, *args, **kwargs): 
...   HTMLParser.__init__(self, *args, **kwargs) 
...  self._text = [] 
...   self._tags_to_drop = set(tags_to_drop) 
...  def clear_text(self): 
...   self._text = [] 
...  def get_text(self): 
...   return ''.join(self._text) 
...  def handle_starttag(self, tag, attrs): 
...   if tag not in self._tags_to_drop: 
...    self._text.append(self.get_starttag_text()) 
...  def handle_endtag(self, tag): 
...   self._text.append('</{0}>'.format(tag)) 
...  def handle_data(self, data): 
...   self._text.append(data) 
... 
>>> td = TagDropper([]) 
>>> td.feed('A line of text\nA line of text with an <img url="foo"> tag\nAnother line of text with a <br> tag\n') 
>>> print td.get_text() 
A line of text 
A line of text with an <img url="foo"> tag 
Another line of text with a <br> tag 

I spadać img tagów ...

>>> td = TagDropper(['img']) 
>>> td.feed('A line of text\nA line of text with an <img url="foo"> tag\nAnother line of text with a <br> tag\n') 
>>> print td.get_text() 
A line of text 
A line of text with an tag 
Another line of text with a <br> tag 
+1

Świetne, dziękuję! Myślę, że pójdę na razie do regex, ponieważ wydaje się, że zawiera mniej kodu (uprość, uprość!). – blz

0

Moje rozwiązanie to:

def remove_HTML_tag(tag, string): 
    string = re.sub(r"<\b(" + tag + r")\b[^>]*>", r"", string) 
    return re.sub(r"<\/\b(" + tag + r")\b[^>]*>", r"", string) 
Powiązane problemy