reguliere expressie match de 'binnenste' waardes?
Code (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
27
28
29
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
27
28
29
$string = '<h2>bovenste</h2>';
$string .= '<h2> titel 1 </h2>';
$string .= 'einde';
$string .= '<h2> titel 2 </h2>';
$string .= 'einde';
$regex = "/<h2>(.*?)einde/is";
preg_match_all($regex, $string, $matches);
print_r($matches);
[/quote]
(ik gebruik de quote blokjes omdat er op dit forum blijkbaar dee code-blokjes zijn).
De output van bovenstaande is dit array:
[quote]Array
(
[0] => Array
(
[0] => <h2>bovenste</h2><h2> titel 1 </h2>einde
[1] => <h2> titel 2 </h2>einde
)
[1] => Array
(
[0] => bovenste</h2><h2> titel 1 </h2>
[1] => titel 2 </h2>
)
)
$string .= '<h2> titel 1 </h2>';
$string .= 'einde';
$string .= '<h2> titel 2 </h2>';
$string .= 'einde';
$regex = "/<h2>(.*?)einde/is";
preg_match_all($regex, $string, $matches);
print_r($matches);
[/quote]
(ik gebruik de quote blokjes omdat er op dit forum blijkbaar dee code-blokjes zijn).
De output van bovenstaande is dit array:
[quote]Array
(
[0] => Array
(
[0] => <h2>bovenste</h2><h2> titel 1 </h2>einde
[1] => <h2> titel 2 </h2>einde
)
[1] => Array
(
[0] => bovenste</h2><h2> titel 1 </h2>
[1] => titel 2 </h2>
)
)
Dus deze gaat fout:
[0] => <h2>bovenste</h2><h2> titel 1 </h2>einde
dat moet zijn:
[0] => <h2> titel 1 </h2>einde
Hoe maak je een regex die dat doet?
Gewijzigd op 24/09/2010 10:43:11 door Bas IJzelendoorn
Als de kans bestaat dat er meerdere h2-tags vóór het te matchen pattern staan, zul je dat expliciet moeten afvangen. Je krijgt dan iets als:
Er is misschien een elegantere oplossing, maar ik heb vandaag helaas geen tijd om daarover na te denken. Ik probeer er morgen op terug te komen.
met die code veranderd er wel iets, maar het eerste resultaat is anders, heel bizar.
dit is de output:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Array
(
[0] => Array
(
[0] => <h2>bovenste</h2><h2> titel 1 </h2>einde
[1] => <h2> titel 2 </h2>einde
)
[1] => Array
(
[0] => titel 1 </h2>
[1] => titel 2 </h2>
)
)
(
[0] => Array
(
[0] => <h2>bovenste</h2><h2> titel 1 </h2>einde
[1] => <h2> titel 2 </h2>einde
)
[1] => Array
(
[0] => titel 1 </h2>
[1] => titel 2 </h2>
)
)
Dus die eerste is nog wel :
[0] => <h2>bovenste</h2><h2> titel 1 </h2>einde
maar in het 2de subarray geeft ie bij tussenliggende waardes wel de juiste content terug!?
[0] => titel 1 </h2>
Ik heb nog zitten zoeken en kwam dit tegen:
http://www.ibm.com/developerworks/library/os-php-regex2/index.html?ca=drs-&ca=dkw-php#list4
probeerde er iets als dit mee:
$regex = "/einde(?<=h2)/is";
maar dat doet niks.
Dank je wel. Hier kan ik mee verder!
Toevoeging op 22/09/2010 10:08:45:
O, nee. Hij ziet nu wel het juiste begin, maar gaat niet tot het einde.
Het probleem met die lookbehind assertions die je van de IBM-site hebt geplukt, is dat de string 'einde' alleen matcht als meteen daarachter '<h2>' staat. Het werkt dus niet bij de laatste match of zelfs als er een spatie achter 'einde' staat.
Dan zou ik dit als output verwachten:
Het begin van de string matcht dus ook op het deel (?:<h2>.*<\/h2>)? en vandaar staat <h2>bovenste</h2> ook in Array[0][0].
Reguliere expressies zijn van nature greedy, dus ze proberen zoveel mogelijk te matchen. Als je verwachting niet klopt met de resultaten, dan ligt het meestal daaraan ;-)
Edit: Ik moest even zoeken, maar vorig jaar heb ik al eens in een reactie een verhaal geschreven over negative lookahead assertions. Eigenlijk is dat verhaal hier ook toe te passen: je wilt namelijk niet de string <h2> in je match hebben.
Ik laat het aan jou om het eerst zelf te proberen. Als je er niet uit komt, help ik je wel weer verder.
Gewijzigd op 25/09/2010 11:48:34 door Willem vp