[PHP] html in reguliere expressie

Pagina: 1
Acties:

Onderwerpen


  • robindv
  • Registratie: Juli 2009
  • Laatst online: 25-08 20:40
Hoi,

ik heb documenten waarin ongeveer 30x de volgende regel staat
HTML:
1
2
3
4
5
6
<TD colspan=6 rowspan=2 align="center" nowrap="1" bgcolor="#FFFFFF" ><TABLE><TR><TD width="50%" bgcolor="#FFFFFF"  nowrap=1><font size="2" face="Arial" color="#000000">
(var 1)
</font> </TD>
<TD width="50%" bgcolor="#FFFFFF"  nowrap=1><font size="2" face="Arial" color="#000000">
(var 2)
</font> </TD>

Nu wil ik var1 en var 2 filtreren uit dit 400 regels beslaande html-document.
Ik dacht een een preg match, maar dan moet van bovenstaande code een reguliere expressie gemaakt worden, en dan loopt die tegen de <,>, # aan.

Kan iemand bovenstaande html-code tot een reguliere expressie ombouwen? Want ook na googelen lukt het me niet....

  • jbdeiman
  • Registratie: September 2008
  • Laatst online: 07:08
@robindv
Escapen met de \ wil wel eens helpen bij die tekens..:) Succes

  • Luqq
  • Registratie: Juni 2005
  • Nu online
HTML parsen met reguliere expressies is faal. Je kan dit beter vanuit de XHTML tree opbouwen

  • Jaap-Jan
  • Registratie: Februari 2001
  • Laatst online: 07:06

| Last.fm | "Mr Bent liked counting. You could trust numbers, except perhaps for pi, but he was working on that in his spare time and it was bound to give in sooner or later." -Terry Pratchett


  • Ram0n
  • Registratie: Maart 2002
  • Laatst online: 03-07 13:05

Ram0n

Bierbrouwende nerd

Voorstel 1: escape die speciale characters met backslashes, één keer werk en dan ben je klaar. Met een regex tool als Regexr kan je dan ook nog eens live zien (terwijl je de expression maakt) of hij juist matched.

Voorstel 2: zoals hierboven aangegeven zijn regular expressions niet echt handig hiervoor, je kan het wellicht beter parsen met een html-parser (simpel in bijvoorbeeld php) en dan simpelweg de juiste waarden opvragen.

Moet je dit eenmalig doen? Dan zou ik optie 1 aanraden, die is dénk ik wat sneller en makkelijker te maken. Maar als je dit in de toekomst nog eens tegen denkt te komen zou ik juist de laatste aanraden.

[ Voor 3% gewijzigd door Ram0n op 19-11-2009 18:18 ]

Eigenaar/brouwer Milky Road Brewery


  • pedorus
  • Registratie: Januari 2008
  • Niet online
Every time you attempt to parse HTML with regular expressions, the unholy child weeps the blood of virgins, and Russian hackers pwn your webapp. Parsing HTML with regex summons tainted souls into the realm of the living.[...]
Cool, ik zou normaal DOMDocument aanraden, maar het lijkt me duidelijk dat een regex veel interessanter is. ;)
PHP:
1
2
3
4
if (preg_match_all(
    '$<font size="2" face="Arial" color="#000000">\s*+(.*?)\s*+</font>$i',
    $html,$matches)>0)
   print_r($matches[1]);

Zoals je ziet hoeft er niets geescaped te worden. \s*+ is alle whitespace zonder backtracking consumeren, .*? is zo min mogelijk tekens (let op: . matcht niet alles met deze instellingen, dus dit werkt alleen bij 1-regelige variabelen).

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


  • Cartman!
  • Registratie: April 2000
  • Niet online
Ik zou dit ook doen met DOM-functies en bijv. XPath, daar is t voor gemaakt.


<insert ondertitel over regexes>

[ Voor 19% gewijzigd door Cartman! op 19-11-2009 19:19 ]


  • Ram0n
  • Registratie: Maart 2002
  • Laatst online: 03-07 13:05

Ram0n

Bierbrouwende nerd

pedorus schreef op donderdag 19 november 2009 @ 19:06:(let op: . matcht niet alles met deze instellingen, dus dit werkt alleen bij 1-regelige variabelen).
Een "s" toevoegen aan het einde laat het over meerdere regels matchen toch?

Eigenaar/brouwer Milky Road Brewery


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Ram0n schreef op donderdag 19 november 2009 @ 23:18:
[...]

Een "s" toevoegen aan het einde laat het over meerdere regels matchen toch?
m voor zover ik weet.

En dit ga je inderdaad niet met regexps willen doen. Het kán vast wel, zelfs in een paar regeltjes. Maar intussen is het zo onderhoudbaar als een huis dat zonder fundering in het moeras is gebouwd. ;)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 08:28

crisp

Devver

Pixelated

Nee, multi-line mode is dat de $ het einde van de regel matched ipv het einde van de input, s is wel degelijk 'dot-matches-all' (in de meeste PCRE-like implementaties).
En dit ga je inderdaad niet met regexps willen doen. Het kán vast wel, zelfs in een paar regeltjes. Maar intussen is het zo onderhoudbaar als een huis dat zonder fundering in het moeras is gebouwd. ;)
Als je dit al met string-based functions zou willen doen dan kom je imo ook een heel eind met strpos() and the like. Waarschijnlijk nog een stuk efficienter ook :)

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

crisp schreef op vrijdag 20 november 2009 @ 00:15:
[...]

Nee, multi-line mode is dat de $ het einde van de regel matched ipv het einde van de input, s is wel degelijk 'dot-matches-all' (in de meeste PCRE-like implementaties).
Ah, ik had eroverheen gelezen dat het specifiek om de . ging. :)
Als je dit al met string-based functions zou willen doen dan kom je imo ook een heel eind met strpos() and the like. Waarschijnlijk nog een stuk efficienter ook :)
Stringfuncties zijn sneller, DOM-functies zijn iets onderhoudbaarder. Ik zou zelf denk ik voor de DOM-oplossing gaan. :P

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Toch blijft een goede daad nooit onbestraft:
PHP:
1
2
3
4
5
6
$doc = new DomDocument();
if (@$doc->loadHTML($html)) {
    $xpath = new DomXpath($doc);
    foreach($xpath->query('//font[@size=2][@face="Arial"][@color="#000000"]') as $node)
        echo $node->nodeValue . "\n";
}

En trager, en langer, en misschien ook nog ingewikkelder voor mensen die geen XPath praten. :) Eigenlijk hadden ze DomDocument wat handiger moeten schrijven:
PHP:
1
2
3
if ($doc = DomDocument::fromHTML($html))
    foreach($doc->xpath('//font[@size=2][@face="Arial"][@color="#000000"]') as $node)
        echo $node->nodeValue . "\n";

(werkt helaas (vooralsnog) niet)

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Moet je Zend Framework eens downloaden, daar kun je met Zend_Dom wel direct zulke dingen doen.

Uit de manual:
PHP:
1
2
3
4
5
6
7
$dom = new Zend_Dom_Query($html);
$results = $dom->query('.foo .bar a');

$count = count($results); // get number of matches: 4
foreach ($results as $result) {
    // $result is a DOMElement
}
Pagina: 1