głębokość limit tag.text

głosy
0

Po prostu nie mogę zrobić to dobrze. BeautifulSoup4 jest tak mylące.

Próbuję naprawić nietopione Markdown odniesień w tekście HTML. Regex jest:

REF = re.compile(r\[(?P<title>.+?)\]\[(?P<identifier>.*?)\])

Ponieważ pozornie BS4 zastosowań matchwyrażeń regularnych, zrobiłem regex szersza z

REF = re.compile(r.*\[(?P<title>.+?)\]\[(?P<identifier>.*?)\].*, re.DOTALL)

Celem jest znalezienie takich ciągów i zastąpienie ich rzeczywistych <a>powiązań, ale jeśli nie są one w <code>tagu (niezależnie od głębokości). Mam mapowanie aby uzyskać adres URL z identifier.

[<code>title<code>][identifier]powinny być dopasowane, ale <code>[title][identifier]</code>nie powinno.

Jeśli wejście jest:

<p>[<code>title<code>][identifier]</p>

Wyjście powinno być:

<p><a id=identifier href=http://example.com><code>title<code></a></p>

Jednak następujące wejściowe powinny pozostać nienaruszone:

<p><code>[title][identifier]</code></p>

Próbowałem następujące:

tags = [tag.parent for tag in soup.find_all(text=REF) if not tag.find_parent(code)]

... ale brakowało tagi. Znalazłem wyjaśnienie w tym poście: BeautifulSoup - szukaj według tekstu wewnątrz znacznika . Wydaje się text(albo nowa nazwa string, choć uważam, że zachowanie się być różne) powróci None, gdy istnieją inne znaczniki w tagu, co oznacza, że tag <p>[<code>title<code>][identifier]</p>nie zostanie dopasowane.

Myślę również, że post dał rozwiązanie:

tags = list(
    soup.find_all(
        lambda tag: tag.name != code and
                    not tag.find_parent(code) and
                    REF.search(tag.text)
    )
)

... ale teraz zamiast dać mi tagi blisko liści, zwraca tagów korzeniowych jak <html>i <body>, ponieważ tag.textzwraca pełny, rekurencyjne tekst wszystkich potomków . Potem oczywiście tych tagów zawiera tekst pasujący do wyrażenia regularnego, ale wewnątrz <code>znaczników .

Najlepszym rozwiązaniem, jak sądzę, byłoby spróbować regex przed tekstem tagu ograniczony do pewnej głębokości. Jeśli głębokość 1 tekst <p>[<code>title</code>][identifier]</p>jest [ ][identifier]i głębokości 2 tekst o tym samym znacznikiem jest [<code>title</code>][identifier], to głębokość-2 to wszystko potrzeba ja.

Czy istnieje sposób, aby to zrobić? A może masz jakieś inne rozwiązanie w umyśle? Pomyślałem, że może mógłbym iteracyjne na wszystkich tagów z liści do korzeni, wszerz, ale ja nadal będę miał ten sam problem z tag.textpowrotem tekst wszyscy potomkowie, jak również.

Utwórz 19/03/2020 o 22:00
źródło użytkownik
W innych językach...                            

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more