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ń match
wyraż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.text
zwraca 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.text
powrotem tekst wszyscy potomkowie, jak również.