Regex vraag

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • vorlox
  • Registratie: Juni 2001
  • Laatst online: 02-02-2022

vorlox

I cna ytpe 300 wrods pre miute

Topicstarter
Beste Allemaal,

Ik ben niet zo'n regex koning als ik wel zou willen zijn en ik loop flink vast nu.
Uit een systeem waar ik geen grip op heb komt een stukje HTML code.
Nu zou ik dit graag omzetten naar een array

PHP:
1
$string = "<table><td>data 1</td></table><table><td>data 2</td></table>";


Nu wil ik dus graag data1 apart hebben.
En ik dacht slim te doen met de volgende regex.

code:
1
#<table>(.*)</table>#is'


Echter hiermee krijg ik alles tussen de eerste table en de laatste.

Dus ik heb er nog een paar geprobeerd maar het wil niet lukken.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$patterns = array(
    '#<table>(.*)</table>#is',
    '#<table>([^</table]*)</table>#is',
    '#<table>(?!</table))*#is',
);

echo "<pre>"; 
foreach($patterns as $pat) {
    echo "Pattern: ".htmlspecialchars($pat)."<br>";
    preg_match($pat, $string, $matches);
    foreach($matches as $i => $m) {
        echo $i." = ".htmlspecialchars($m)."\n";
    }
    echo "<hr>";
}
echo "</pre>";


Maar de uitkomst is niks
code:
1
2
3
4
5
6
7
8
9
Pattern: #<table>(.*)</table>#is
0 = <table><td>data 1</td></table><table><td>data 2</td></table>
1 = <td>data 1</td></table><table><td>data 2</td>
--------------------------------------------------------------------------------
Pattern: #<table>([^</table]*)</table>#is
geen uitkomst
--------------------------------------------------------------------------------
Pattern: #<table>(?!</table))*#is
geen uitkomst


Iemand een TIP?

[ Voor 18% gewijzigd door vorlox op 12-12-2011 21:15 ]


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Voor dit soort dingen gebruik je een sglr parser, niet regexes.

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 15-09 09:10
Of gewoon simpelweg een DOM-parser welke al in PHP zit. SimpleXML is een heel eenvoudig en mooi voorbeeld hiervoor. Je kunt namelijk ook gewoon - valide - html parsen.

Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

En als het dan toch met regexps moet (wat inderdaad geen goed plan is), waarom zoek je dan naar de tabletag als je de td wil hebben?

'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!

  • vorlox
  • Registratie: Juni 2001
  • Laatst online: 02-02-2022

vorlox

I cna ytpe 300 wrods pre miute

Topicstarter
Uhm ik heb zitten stoeien met de simple xml maar dan krijg ik een flink object terug.
In mijn case is het wat uitgebreider dan het voorbeeld hierboven.

Ik dacht als ik nu eerst <table>*</table> eruit krijg en het dan naar een Dom gooi dan kan ik daar mooi in plukken.

Het is namelijk redelijk dynamisch de data die ik terugkrijg dus zoiets als $xml->body->table[0]-> etc is nogal gevaarlijk.

Zou het uberhaupt kunnen wat ik wil..das even de vraag anders is het door stoeien met een Dom doc.

Acties:
  • 0 Henk 'm!

  • C0rnelis
  • Registratie: Juni 2010
  • Laatst online: 26-08 22:21
Ik weet niet hoe groot de maximale output is die je terug krijgt, maar je kan de performance altijd even bekijken.
Als je je gehele html in een DOMDocument object stopt, dan kan je gewoon door de tabellen itereren ipv
body->table[0] of wat dan ook te gebruiken (ook al is er maar 1 table).

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$html = $output;

$dom = new DOMDocument();

$dom->loadHTML($html);

$dom->getElementsByTag('table');

foreach($tables as $table) {
  $rows = $table->getElementsByTag('tr');
  foreach($rows as $row) {
    $cells = $row->getElementsByTag('td');
    var_dump($cells);
  }
}


Bovenstaande code is niet getest.

Afhankelijk van de hoeveelheid whitespace in je originele output kan deze regel blijkbaar ook nog geheugen schelen (wederom, dit is ook nogal afhankelijk van je html)
PHP:
1
$dom->preserveWhiteSpace = false;

[ Voor 14% gewijzigd door C0rnelis op 12-12-2011 22:21 ]


Acties:
  • 0 Henk 'm!

  • vorlox
  • Registratie: Juni 2001
  • Laatst online: 02-02-2022

vorlox

I cna ytpe 300 wrods pre miute

Topicstarter
Ik heb idd even zitten rommelen met de simple_xml....Dom Doc was mijn 2e keuze geweest.
Ik kan de table onderscheiden omdat er een caption "Kleurinformatie" in zit..dus dat is al lekker.
Heb nu het volgende. tis niet het netste wat ik voor ogen had ...maar goed had de maker van die interface maar een soap/json/xml koppelingetje moeten maken.
Tis overigens wel rommel hoor wat dat ding uitspuugt en is zelfs gemaakt door VAG...had ik wat beters van verwacht.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
        $colorMapping = array(
            'model',
            'kleurcode',
            'laknummer',
            'omschrijving'
        );
        
        //Load Xml
        $xml = simplexml_load_string($resultData);
                
        //Loop tables
        foreach($xml->body->form->table as $node) {
            if(isset($node->caption) && strtolower($node->caption) == 'kleurinformatie') {
                //Loop tr's
                foreach($node->tbody->tr as $trNode) {
                    //Loop td's
                    $i = 0;
                    $item = array();
                    foreach($trNode->td as $tdNode) {
                        $item[$colorMapping[$i]] = trim($tdNode{0});
                        $i++;
                    }
                    $list['kleurinformatie'][] = $item;
                }
            }
        }


Het werkt

Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

Rommel? Waarom? Omdat het meer doet dan jij er nu mee wil doen? :?

'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!

  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 15-09 09:10
Om alle overbodige rommel eruit te halen zou je door PHP ook nog bepaalde tags weg laten strippen (of juist preserveren). Dit kun je doen met de functie strip_tags.

Acties:
  • 0 Henk 'm!

  • vorlox
  • Registratie: Juni 2001
  • Laatst online: 02-02-2022

vorlox

I cna ytpe 300 wrods pre miute

Topicstarter
@NMe
Je zou de HTML code eens moeten zien wat dat ding uitspuugt..lol...is toch echt zooo 1999. Werkt niet in FF of chrome....IE only. TAGS met hoofdletters, tables tables en tables...en niet alleen voor tabular data.
Maar goed het doet wat het moet doen.

Thanks m8 _/-\o_

[ Voor 34% gewijzigd door vorlox op 13-12-2011 00:17 ]


Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

Hoezo, uitspuugt? Je wil er toch juist HTML in stoppen en data eruit halen?

'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!

  • C0rnelis
  • Registratie: Juni 2010
  • Laatst online: 26-08 22:21
vorlox doelt op de inhoud van $resultData die wordt geleverd door een extern systeem.
vorlox schreef op maandag 12 december 2011 @ 21:14:
Beste Allemaal,

[..]
Uit een systeem waar ik geen grip op heb komt een stukje HTML code.
Nu zou ik dit graag omzetten naar een array

[..]

Acties:
  • 0 Henk 'm!

  • vorlox
  • Registratie: Juni 2001
  • Laatst online: 02-02-2022

vorlox

I cna ytpe 300 wrods pre miute

Topicstarter
Lol juist...volgens mij reageerde je op het verkeerde stukkie NMe...C0rnelis had het bij het rechte eind.

Ik doelde idd op dat oude systeem waar ik mijn data vandaan moet halen. Die spuugt ouderwetse code uit.
In principe geen probleem alleen jammer als je daarmee wat moet doen ipv alleen bekijken in een browser.
Echter dat het niet werkt in FF enz...vind ik zelf gewoon jammer...volgens mij zijn dit soort dingen met kleine ingrepen toch te verhelpen...ik zocht nog naar een "Best viewed with NS4" icoontje hahaha

Acties:
  • 0 Henk 'm!

  • Wolfboy
  • Registratie: Januari 2001
  • Niet online

Wolfboy

ubi dubium ibi libertas

Het probleem met je regex is overigens dat ie greedy is :)

Als je dit gebruikt dan doet het wel wat je wilt: (let op het vraagteken)
code:
1
#<table>(.*?)</table>#is'

Blog [Stackoverflow] [LinkedIn]


Acties:
  • 0 Henk 'm!

  • DataGhost
  • Registratie: Augustus 2003
  • Laatst online: 19-09 21:26

DataGhost

iPL dev

Wolfboy schreef op dinsdag 13 december 2011 @ 02:40:
Het probleem met je regex is overigens dat ie greedy is :)

Als je dit gebruikt dan doet het wel wat je wilt: (let op het vraagteken)
code:
1
#<table>(.*?)</table>#is'
Nee, het probleem met z'n regex is dat HTML niet regulier is. Meer details hier

Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

Gelukkig zei men dat al in de tweede en derde post. ;)

'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!

  • Wolfboy
  • Registratie: Januari 2001
  • Niet online

Wolfboy

ubi dubium ibi libertas

DataGhost schreef op dinsdag 13 december 2011 @ 08:20:
[...]

Nee, het probleem met z'n regex is dat HTML niet regulier is. Meer details hier
De string die hij probeert de matchen is regulier dus dat is hierbij niet van toepassing.
Sowieso gaat de rest van het topic al over hoe je het goed moet doen :P

Daarnaast... al is een goede SGML parser een beter idee, als je snel wat wil parsen dan heb je met 1 regel al een regex die zoiets als dit parsed en zeker 5x meer code als je het netjes wil parsen. Het hangt helemaal van je use-case af of het een acceptabele (note, geen goede) oplossing is.

Blog [Stackoverflow] [LinkedIn]


Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

Oh, het kan zeker ook een goede oplossing zijn hoor. Mits je tenminste zelf de controle (of bij gebrek daaraan: invloed) hebt over de HTML die als invoer dient en het probleem te reduceren valt tot één of twee regular expressions zonder al te veel poespas. Of bijvoorbeeld bij een eenmalige data-import waarvan je weet dat de code niet robuust hoeft te zijn en in principe na een succesvolle import direct weggegooid wordt.

Ik weet dat dat is wat je met "acceptabele oplossing" bedoelde, maar in gevallen als bovengenoemde is het meer dan dan. In voldoende kleine probleemdomeinen kan het een prima oplossing zijn om dit met regular expressions op te lossen.

'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.

Pagina: 1