Regex Suche

caesar94

Cadet 4th Year
Registriert
Dez. 2013
Beiträge
65
Hallo Boardies,

hoffentlich passt mein Thread einigermasen in diesen Bereich.
Ich benötige Hilfe mit einer Regular Expression (Regex), die mir beim Suchen gewissen Stichwörter in einem HTML Dokument helfen soll.

So sieht das immer wiederkehrende Muster des HTML Codes aus:
Code:

HTML:
<tr>
  <td width="170px">
	  <img src="imgsource" />
	</td>
  <td>
	  <strong>WICHTIG</strong><br />
		WICHTIG<br />
		WICHTIG<br />
		WICHTIG<br />
		<a href="URL" target="_blank">Text</a><br />
		<br />
		
  </td>
</tr>
<tr>
  <td colspan="2" style="border-bottom: 1px solid #ccc;"></td>
</tr>

Alles was als WICHTIG betitelt ist möchte ich herauspicken.
Man könnte also sagen, alles zwischen <strong> und <a href=".

Ich habe mir bereits ein Regex zusammengeschustert, das Text zwischen zwei HTML-Tags findet, jedoch nicht über mehrere Zeilen wie es im obigen HTML-Code ist.

(?<=<strong>).*?(?=</strong><br />)
Dieser Regex findet z.B. alles zwischen <strong> und </strong><br />, jedoch habe ich es nicht geschafft, dass er alles zwischen zwei Tags, welche nicht in der selben Zeile sind findet.

Kann mir kemand von euch weiterhelfen?
Was mache ich falsch?

Vielen Dank.
 
Sofern du die HTML-Seite innerhalb deines Programms als String vorliegen hast, würde ich vor der Regex-Suche einfach die Zeilenumbrüche entfernen und fertig...

In Java in etwa so:
Code:
String html = "...";
html = html.replaceAll("\n", "");
 
Naja,

das erste findest Du mit
<\s*strong\s*>(.*)<\/\s*strong\s*>\s*<\s*br\s*\/>


Die anderen mit
.*strong\s*>\s*<\s*br\s*\/>\s*((?:.|\n)*)(?:\s*<a\s*href)

aus denen Du dann die WICHTIG Teile extrahierst

z.B. dann mit
\s*(.*)<br
 
HominiLupus schrieb:
Du benutzt Regex für etwas wofür es nicht gemacht ist. (HTML parsen).
https://www.google.de/search?q=beautifulsoup

Ich kenne mich da nicht so gut aus, aber ich dachte, dass HTML Parser eben Regex verwenden.
Weshalb kann ich hier kein Regex verwenden bzw. wieso ist Regex hier nicht sinvoll?
Vielen Dank für den Link, werde mir das mal anschauen, leider kann ich kein Python, also mal sehen.

miac schrieb:
Naja,

das erste findest Du mit
<\s*strong\s*>(.*)<\/\s*strong\s*>\s*<\s*br\s*\/>


Die anderen mit
.*strong\s*>\s*<\s*br\s*\/>\s*((?:.|\n)*)(?:\s*<a\s*href)

aus denen Du dann die WICHTIG Teile extrahierst

z.B. dann mit
\s*(.*)<br

Die erste Regex funktioniert bei mir, die zweite leider nicht.
Ich benutze im Moment Notepad++ zum ausführen der Regex.

Kann es am Programm liegen, oder muss ich sonst irgendetwas beachten?
 
Zuletzt bearbeitet:
Du kannst das z.B. hier testen, dann siehst Du auch die Matches:
http://regex101.com/#javascript

Noch was zu HTML/XML Parser

Natürlich kann man das machen, insbesondere wenn Inline Styles verwendet werden. Für einfache Sachen in das aber übertrieben.

Da wird ja letztendlich immer ein DOM Tree aufgebaut, durch den man dann auch hächeln muß und dort muß man dann auch Regeln festlegen, welche Tags und Ausprägungen einen interessieren. Da ist ein RegEx einfacher.
 
Zuletzt bearbeitet:
Einer der praktischen Hauptgründe ist, weil HTML verschachtelt ist. Was ist wenn irgendwo in deinem <WICHTIG> in Link ist? dann wird dieser Link genommen und der Rest abgetrennt.

Zudem wird es auch in der Sprache deiner Wahl (welche denn?) eine Lib existieren die HTML parsen kann.
 
Wäre die Frage wo das HTML herkommt. Dateien auf der Festplatte? Eine Webseite / Server?
Sowas könnte man auch ganz einfach im Browser machen.
HTML:
<template>
<strong>BLAAA</strong>
<a href="URL">Text</a>
</template>

<script>
var temp = document.querySelector("template").content;
var text = temp.querySelector("strong").textContent;
var url = temp.querySelector("a").getAttribute("href");

copy(text);
</script>

Und schon ist BLAAA in der Zwischenablage. (Glaub ich zumindest, habs nicht getestet)
 
Zuletzt bearbeitet:
HominiLupus hat schon recht, auch wenn seine Erklärung ("regex sind für normale Sprachen entwickeltes Werkzeug") etwas arg frei interpretiert ist. Ich wollte hier erst versuchen, das ganze genauer zu erläutern, aber es ist im Rahmen eines Postings hier ein Fass ohne Boden und wird vermutlich doch nicht verstanden - bei Interesse mal nach Chomsky-Hierarchie googeln und alles lesen, was damit in Zusammenhang steht. Jedenfalls ist HTML ist keine reguläre Sprache (sondern mindestens mal kontext-frei) und somit auch nur bedingt geeignet, um mit regulären Ausdrücken durchsucht zu werden. Um das zu verstehen, muss man sich etwas einlesen, kann es sich dann am Beispiel HTML aber sehr gut klar machen, wenn man zum Beispiel verschachtelte Strukturen betrachtet.

Das ganze ist jedoch die akademische Sicht. Die Regex-Implementierungen moderner Sprachen sind nicht mehr nur einfach regulär, sondern werden durch Dinge wie look-behinds etc. auch etwas kontext-frei, womit man sie prinzipiell schon auf viele Problemstellungen im HTML-Umfeld loslassen kann. Das ändert aber nichts daran, dass reguläre Ausdrücke bei HTML nicht Mittel der Wahl sind, aus so vielen anderen Gründen. Beispiel: Webseiten können XML-konform ausgeliefert werden oder nicht, beides ist gültig, beides sieht anders aus, selbst wenn der DOM-Baum exakt der selbe ist. HTML Parser juckt das nicht, reguläre Ausdrücke schon, sofern diese Tags miteinbeziehen.

miac schrieb:
Noch was zu HTML/XML Parser
Natürlich kann man das machen, insbesondere wenn Inline Styles verwendet werden. Für einfache Sachen in das aber übertrieben.

Eher andersrum. Man kann es nicht machen, man sollte es machen. Reguläre Ausdrücke kann (könnte) man machen, aber nur bei einfachen und eindeutigen Sachverhalten.
Das mit dem Übertrieben ist auch eher Ansichtssache, sehe ich eher nicht so. Klar, man muss meistens eine Bibliothek einbinden, aber das ist ja eine einmalige Sache. Alles nachfolgende ist einfacher, vom Code her nicht länger und führt auch garantiert zum Ziel. Die meisten Problemstellungen sind ein No-Brainer, wenn man z.B. xpath auf den Tree anwendet. Bei regulären Ausdrücken sprengt es ziemlich schnell die Gehirnwindungen. Da muss die Aufgabenstellung wirklich einfach sein, wenn man eine robuste Lösung möchte.
 
miac schrieb:
Du kannst das z.B. hier testen, dann siehst Du auch die Matches:
http://regex101.com/#javascript

Die zweite Regex funktioniert für mich auch in oben genannter Webapp nicht.
Dieser funktioniert nur, wenn der Beispiel HTML-Code von mir nur einmal vorkommt, da sich das Muster jedoch wiederholt funktioniert er leider nicht mehr.

HominiLupus schrieb:
Zudem wird es auch in der Sprache deiner Wahl (welche denn?) eine Lib existieren die HTML parsen kann.

c#
Ich werde es nun mal mit dem HTML Agility Pack für .NET versuchen.

T0a5tbr0t schrieb:
Wäre die Frage wo das HTML herkommt. Dateien auf der Festplatte? Eine Webseite / Server?
Sowas könnte man auch ganz einfach im Browser machen.
Kommt von einem Server. Du meinst also mit Javascript?
Ich kann mir nicht vorstellen, dass das mein Problem löst.



Ich bin mir ehrlich gesagt noch immer nicht ganz sicher, was nun der bessere Ansatz ist um genau mein Problem zu lösen.
Auf jeden Fall werde ich es nun mal mit einem HTML Parser versuchen.
Wenn jedoch jemand einen Lösungsansatz mit Hilfe von Regex hat, immer her damit.

Vielen Dank für die ganzen tollen und hilfreichen Antworten.
 
Zuletzt bearbeitet:
Zuletzt bearbeitet:
Die frage der Quelle ist ja eigentlich am wichtigsten, dann kann man das sinnvollste Tool wählen.
Ist das eine große Seite, mehrere kleine? Wie viele? Ist die Anzahl begrenzt? Soll das nur ein mal oder in Zukunft wieder funktionieren?
Theoretisch geht das mit jeder Sprache. Wenn der Server HTTP kann, dann ist JavaScript wohl das einfachste. Keiner kann so gut HTML parsen wie Browser.
 
T0a5tbr0t schrieb:
Die frage der Quelle ist ja eigentlich am wichtigsten, dann kann man das sinnvollste Tool wählen.
Ist das eine große Seite, mehrere kleine? Wie viele? Ist die Anzahl begrenzt? Soll das nur ein mal oder in Zukunft wieder funktionieren?
Theoretisch geht das mit jeder Sprache. Wenn der Server HTTP kann, dann ist JavaScript wohl das einfachste. Keiner kann so gut HTML parsen wie Browser.

Der Seiteninhalt wird abhängig von der Usereingabe dynamisch erstellt, also quasi viele kleine Seiten.
Eigentlich brauch es nur einmal funktionieren, wobei eine generischer Lösungsansatz natürlich immer besser ist, aber warscheinlich mehr Zeit benötigt.
Das mit dem Browser scheint Sinn zu machen, muss mir mal JS und Parsen anschauen.
 
Mir ist noch nicht klar, was die übergeordnete Aufgabe ist? Was willst genau Du eigentlich machen? Wo und mit welcher Technik soll die Auswertung stattfinden?
 
Bestimmt hat jeder von euch auf der Seite eines Herstellers schonmal nach einem Händler in der Gegend gesucht.
Ein fast jeder Hersteller, egal von welchem Produkt, hat eine solche Händlerseite. Hier als Beispiel die Seite von Yamaha. (ACHTUNG: Hier handelt es sich um eine Beispielseite und nicht um die Seite, welchen den von mir oben geposteten, HTML-Code beheerbergt.)

Für meinen Betrieb soll ich nun alle Händler eines Herstellers in der selben Branche herausfinden. Auf Branchenbücher kann man sich hier jedoch nicht verlassen, da diese oft alte und schlecht gepflegte Daten beinhalten.
Am besten eignet sich also die Händlerseite eines großen und nahmhaften Herstellers.

Keine Sorge es handelt sich hier um öffentlich zugängliche Daten und keine Daten von Privatpersonen, außerdem werden die Daten auf keine Fall weitergegeben und könnten zur Not ohnehin von Hand gesammelt werden. In meinen Augen geht also alles mit rechten Dingen zu.

Da ich ein wenig Erfahrung mit der Programmierung in C# bzw. VB.NET und schonmal von Regex gehört habe, möchte ich die Händlerdaten natürlich nicht von Hand sammeln, sondern suche einen bequemeren Weg.
Ergänzung ()

Die Krönung wäre natürlich alles automatisch zu gestalten.
Also auch die GET-Anfrage (diese kann man mithilfe von Browser Plug-Ins wie "FireBug" herausfinden) programmatisch mit der Postleitzahl an den Server zu schicken, den HTML-Code vom Server erhalten. Diesen dann nach den benötigten Informationen zu durchsuchen, die Informationen anschließend zu speichern und die nächste PLZ in Form einer GET-Anfrage an den Server schicken.

So müsste lediglich eine Liste mit PLZs und das Regex bzw. Parser Muster angegeben werden und alles andere würde voll automatisch laufen.
Zumindestens für diese Seite. Bei einer anderen Seite müsste man zusätzlich noch die GET-Anfrage und das Regex Muster anpassen.

Jedoch übersteigt eine solche Anforderung warscheinlich meinen zeitlichen Rahmen und meine derzeitgen Programmierkenntnisse.
Ich würd mich jedoch schon damit begnügen, die PLZ jedes Mal von Hand einzugeben und dann jede HTML-Seite einzeln durchzugehen.
 
Zuletzt bearbeitet:
Das heißt, Du kennst die Webseiten und die Suchbegriffe, nach denen Du die Seite durchsuchen möchtest und willst dann alles in einer Tabelle zusammenfassen?

Schwierig wird es, wenn die Seite dynamisch ist. Wenn man die Seite über Parameter in der URI steuern kann, geht es. Den HTML-Code würde ich mit XPATH parsen.
 
Genau.
Ja die Seite bzw. die Ergebnise verhalten sich dynamisch, deshalb auch der Gedanke mit der Javascript GET-Anfrage.
 
Im Fall deines Yamaha Beispiels braucht man nur das Ajax Request selber bauen und schon hast du alle Daten im JSON Format. (Enthaelt aber mehr als auf der Webseite angezeigt werden, da wohl noch nach Entfernung gefiltert und sortiert wird)

hxxp://de.yamaha.com/de/dealers/?mode=dealer&cat=A01%20A02%20A03%20A04%20A11%20A12&lat=50.6949151&lng=7.138815900000054&pid=&rid=​

Die PLZ wird per Google Maps in Koordinaten umgewandelt und die Kategorie Werte gibt es so: (Kopieren > F12 > Console > Einfuegen > Enter)
Code:
$('#category').find('option').each(function() { 
  console.log($(this).val()) 
});


Vielleicht kannst du uns die Seite mitteilen die du eigentlich meinst.
 
Vielen Dank für die ausführliche und hilfreiche Antwort.
Du hast recht, das Beste wird wohl sein ein wenig konkreter zu werden.

Es handelt sich um mehrere Seiten.

Silit
GEFU
Kaiser

Wenn ich das richtig sehe, müsste pro Seite nur die GET-Anfrage und das Suchpattern abgeändert werden, der Rest der Programmlogik kann bestehen bleiben.

Am Besten konzentrieren wir uns in ersteinmal auf die Seite von Silit.


Ich finde es wirklich beeindruckend wie viele von euch bereit sind mir zu helfen und tolle Beiträge bringen.
Hierfür vielen Dank. Die Community hier ist echt klasse.
 
Zuletzt bearbeitet:
Zurück
Oben