preg_match_all was tun wenn die Daten nicht regelkonform sind?
Hitzering
- php
Hallo,
unsere "interne Suchfunktion" funktioniert so lala. Daher dachte ich mir eine einfache Synonymliste dürfte bessere Ergebnisse bringen.
Die typischen Listen sind wirklich schon super. Jetzt dachte ich mir "wikipedia" bzw. "wiktionary" wird hier noch bessere Daten haben. Und das ist auch so. Leider sind die Daten doch recht ungewöhnlich aufbereitet und enthalten auch mal gerne "individuelle" Absätze / Markierungen die ich gerne Filtere.
Es hat sich herrausgestellt, dass die Synonyme in 99% der Fälle in einer Art <dl> HTML Strukturierung zu finden sind.
Daher bereite ich mir die Datensätzte verschieden vor unter anderem mit
preg_match_all('|<dl>(.*)</dl>|Uism',$quelle, $items_synonyme_2, PREG_PATTERN_ORDER);
vor.
Leider kann man hier: https://de.wiktionary.org/wiki/Familie sehen das es kein zweites öffnendes <dl> gibt. Somit also auch nur 1 Datensatz statt 2 ausgegeben werden siehe:
Quelletext Wiktionary
<p>
<span style="visibility:hidden" id="Synonyme">
<span id="Anker:Synonyme"></span>
</span>
</p>
<div style="margin-bottom:-0.5em; font-weight:bold;" title="bedeutungsgleich gebrauchte Wörter">Synonyme:</div>
<dl>
<dd>[1] <a href="/w/index.php?title=Blutsverwandte&action=edit&redlink=1" class="new" title="Blutsverwandte (Seite nicht vorhanden)">Blutsverwandte</a>,
<a href="/wiki/Sippe" title="Sippe">Sippe</a>
<dl>
<dd>[1a] <a href="/wiki/Kernfamilie" title="Kernfamilie">Kernfamilie</a></dd>
<dd>[1b] <i>abwertend, salopp:</i> <a href="/wiki/Mischpoke" title="Mischpoke">Mischpoke</a></dd>
</dl>
</dd>
<dd>[2] <a href="/wiki/Abart" title="Abart">Abart</a>,
<a href="/wiki/Art" title="Art">Art</a>,
<a href="/wiki/Bereich" title="Bereich">Bereich</a>,
<a href="/wiki/Departement" title="Departement">Departement</a>,
<a href="/wiki/Dialekt" title="Dialekt">Dialekt</a>,
<a href="/wiki/Fach" title="Fach">Fach</a>,
<a href="/wiki/Gattung" title="Gattung">Gattung</a>,
<a href="/wiki/Genus" title="Genus">Genus</a>,
<a href="/wiki/Geschlecht" title="Geschlecht">Geschlecht</a>,
<a href="/wiki/Gruppe" title="Gruppe">Gruppe</a>,
<a href="/wiki/Kategorie" title="Kategorie">Kategorie</a>,
<a href="/wiki/Linie" title="Linie">Linie</a>,
<a href="/wiki/Rasse" title="Rasse">Rasse</a>,
<a href="/wiki/Reihe" title="Reihe">Reihe</a>,
<a href="/wiki/Rubrik" title="Rubrik">Rubrik</a>,
<a href="/wiki/Schlag" title="Schlag">Schlag</a>
</dd>
</dl>
Was kann ich tun um den zweiten Absatz mit zu nehmen? (die <dd> bzw. </dd> benötige ich später noch zum Filtern der individuellen Varianten).
Edit Rolf B: HTML lesbarer gemacht
Hallo Hitzering,
wenn man mal das ganze nicht-strukturelle Brimborium wegnimmt, sieht man, dass hier geschachtelte DLs vorliegen, und das bringt deine Regex durcheinander.
<dl>
<dd>[1] <a href="/w/index.php..." class="new">Blutsverwandte</a>,
<a href="/wiki/Sippe" title="Sippe">Sippe</a>
<dl>
<dd>[1a] <a href="/wiki/Kernfamilie">Kernfamilie</a></dd>
<dd>[1b] ... <a href="/wiki/Mischpoke">Mischpoke</a></dd>
</dl>
</dd>
<dd>[2] <a href="/wiki/Abart">Abart</a>,
<a href="/wiki/Rubrik">Rubrik</a>,
<a href="/wiki/Schlag">Schlag</a>
</dd>
</dl>
Eine Lösung in der Schublade habe ich nicht. Rekursive Regex gibt es, haben aber eine Form, die sich für meine Gehirnwindungen nicht zurechtbiegen lässt.
An Deiner Stelle würde ich den DOM Parser über das HTML Fragment jagen und das entstehende DOM rekursiv durcharbeiten.
Rolf
Danke Rolf, jetzt wo du da so schön aufgeschlüsselt hast stimmt es. Hast du eine Idee/Vorschlag wie ich damit umgehen kann?
Hallo Hitzering,
siehe mein Update des Beitrags. DOM Parser.
Rolf
Danke Rolf,
ich habe mit der Antwort von https://forum.selfhtml.org/self/2019/jul/18/pregmatchall-was-tun-wenn-die-daten-nicht-regelkonform-sind/1753512#m1753512 nicht gerechnet. Die ist genau das richtige für meinen Fall.
Vielen vielen Dank
Hello,
An Deiner Stelle würde ich den DOM Parser über das HTML Fragment jagen und das entstehende DOM rekursiv durcharbeiten.
Das würde ich auf jeden Fall auch tun!
Das hält das Ganze übersichtlich und man ist schnell fertig.
Falls Fragen bestehen, helfe ich am Wochenende gerne vom Desktop. Da habe ich mir diverse Modellcodes gespeichert. Dann muss man nicht jedes Mal das Rad neu erfinden.
Glück Auf
Tom vom Berg
Regex ist nicht geeignet zum parsen von html. Am besten verwendest du einen HTML parser.
Bei deinem Beispiel sind die <dl
verschachtelt. Dafür bräuchtest du ein rekursives Suchmuster.
Etwas in der Art:
preg_match_all('~<dl>(?:[^<]+|<(?!/?dl\b)|(?R))*+</dl>~i',...
Bei (?R)
wird das gesamte Suchmuster wieder eingefügt. Siehe Demo auf Regex101
Danke, das ist super. Ich habe mit der Antwort von https://forum.selfhtml.org/self/2019/jul/18/pregmatchall-was-tun-wenn-die-daten-nicht-regelkonform-sind/1753512#m1753512 nicht gerechnet. Die ist genau das richtige für meinen Fall.
Tach!
Die typischen Listen sind wirklich schon super. Jetzt dachte ich mir "wikipedia" bzw. "wiktionary" wird hier noch bessere Daten haben. Und das ist auch so.
Bist du sicher, dass für deinen Zweck das Parsen der HTML-Ausgabe sinnvoll ist? MediaWiki hat eine API, über die man recht einfach an den Quelltext der Seiten rankommt, ohne Brimborium drumherum und ohne dass die Server dieses Brimborium erzeugen müssen.
Abgesehen von der API kann auch bereits ein angehängtes ?action=raw
helfen, die zu bearbeitenden Daten kleiner zu halten.
dedlfix.
WOW, nein das kannte ich noch nicht. Das vereinfach natürlich alles...
Tach!
WOW, nein das kannte ich noch nicht. Das vereinfach natürlich alles...
Freu dich nicht zu früh. Du musst nun erstmal untersuchen, ob du damit wirklich besser zurecht kommst. Vielleicht ist es ja einfacher HTML mit seinen Start- und End-Tags zu parsen, als in der MediaWiki-Syntax die gleiche Datenstruktur zu finden. Deren Syntax kann manchmal auch schwer nachvollziehbar und/oder komplex geschachtelt sein. Viel Erfolg.
dedlfix.