PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Regulaerer Ausdruck, Zahlen aus HTML Tabelle lesen


pajofego
2009-08-26, 06:59:16
Hallo zusammen beiss mir gerade die Zähne an einem Regex Ausdruck.

Zwischen zwei HTML Tags "<td class=tdRC1> <b> 1,28 </b></td>" steht eine Zahl, in diesem Fall 1,28. Die wuerde ich gerne herauslesen. Problem nur ist das die o.g. html Tags auch mal ohne "<b> </b>" vorkommen koennen. Evt. kann auch class=tdRC1 mal anders aussehen. Die Zahlen alleine bekommen ich durch diesen Ausdruck herausgefiltert:

(\d{1,3},\d{1}\d{1})

Problem ist nur, dass auch andere Zahlen, falls diese vorkommen herausgefiltert werden. Ich wuerde aber nur gerne diese die min. im HTML Tag "<td ... irgendwas> evtl. noch <b> Zahl evt. </b> </td>" steht.

Waere um eine Unterstuetzung dankbar.

Beste Gruesse
pajofego

Monger
2009-08-26, 08:44:17
Das sind so die Fälle, in denen du dir eventuell viel Stress ersparst, wenn du mehrstufig arbeitest. In welcher Sprache programmierst du denn? Bietet die auch Ersetzungen mit Regex an?
Also:

- Inhalt aus der Tabelle extrahieren
- Unliebsame Steuerzeichen rausfiltern: text = Regex.Replace(text, "</?\w>", "")
- Alle Zahlen aus dem Text extrahieren: Regex.Matches(text, "\d{1,3},\d{2}")

Diese Lösung ist möglicherweise ein kleines bißchen inperformanter als wenn du alles in einen Regex Ausdruck reingequetscht kriegst (vorallem wenn die Texte sehr groß werden), aber es liest und wartet sich halt wesentlich einfacher.

Edit: Argh! Sorry, hab dich wohl falsch verstanden. Der erste Schritt ist dein Problem, richtig? Die elegante Lösung wäre wahrscheinlich, das ganze über einen XML Parser rauszuziehen - HTML ist ja im Endeffekt nix anderes als ein Spezialfall von XML. Ansonsten wäre eventuell folgender Ausdruck eine Lösung:

<td class=\w+>.*?<b>(\d{1,3},\d{2})</b>.*?</td>

Die beiden .* Operatoren sind "lazy", damit nur die innerste Schachtelung von <td> ... </td> gecaptured wird. Profis werden sich jetzt die Zehennägel hochrollen, weil Lazy Captures in der Größe verdammt langsam sind. Je nachdem was für einen Regex "Dialekt" du nutzst, könnte man da auch alternativ was mit Atomic Groupings machen. Durch die runden Klammern in der Mitte hast du dann auch gleich ne Capture Group die du auswerten kannst.

pajofego
2009-08-26, 18:43:56
Dank deiner Unterstuetzung konnte ich den Regex Ausdruck wie folgt fuer Boost in C++ erweitern :freak: so dass er zumindestens in den drei von mir ausprobierten Fällen funktionierte.

boost::regex expression("<td class=\\w+>.*?\\s<b>{0,1}\\s(\\d{1,3},\\d{1,3})\\s</b>{0,1}.*?</td>");


XML Parser haette ich gerne verwendet war auch anfangs mein erster Versuch, aber die HTML Seite war fuer den xml Parser in C# nicht verständlich.:mad:

Performance spielt keine Rolle, hauptsache es wird das richtige rausgelesen.

Danke und beste Gruesse
pajofego