[PHP] preg_replace en backreferences

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • JeRa
  • Registratie: Juni 2003
  • Laatst online: 30-04 10:28

JeRa

Authentic

Topicstarter
Ik heb de volgende code:
PHP:
1
2
3
4
5
$string = 'abba';

$string = preg_replace('/(a|b)(.*?)(\1)/is', '!$2!', $string);

echo $string;

Ik maak gebruik van een backreference in de regex, zodat er een combinatie van twee dezelfde characters wordt gevonden. In dit geval zijn dit 'a..a' en 'bb'. Nu is mijn verwachte output:
code:
1
!!!!

Maar de daadwerkelijke output is:
code:
1
!bb!

En dit snap ik niet :) waarom voldoet 'bb' niet aan de expressie? Als ik $string niet instantieer op 'abba' maar op 'bb' werkt het wél.

ifconfig eth0 down


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 21:18

crisp

Devver

Pixelated

'bb' voldoet wel aan de expressie, maar 'abba' ook en komt eerder :)
Een replace is niet recursief in zichzelf, als je dat wilt dan zal je dat zelf in moeten bouwen.

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • pimlie
  • Registratie: November 2000
  • Laatst online: 16:52
Jij verwacht dat als a..a is gematch, de regex verder gaat met de .bb. Dat gebeurt echter niet, want die bb die is al gematched. Die zit in $2. Dus voor de regex is er geen tekst meer over om op te gaan matchen.
Je kan dit makkelijk zien door de regex in een preg_match_all te stoppen, deze stopt alle iteraties van je regex in een array. Als je dan de regex uitvoert op abba dan krijg je 1 resultaat terug, dus 1 iteratie (en dus !!). Als je hem op aabb uitvoert krijg je 2 resultaten terug, dus 2 iteraties en 4!'s

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
preg_match_all('/(a|b)(.*?)(\1)/is', 'abba', $matches);
print_r($matches);
Array
(
    [0] => Array
        (
            [0] => abba
        )

    [1] => Array
        (
            [0] => a
        )

    [2] => Array
        (
            [0] => bb
        )

    [3] => Array
        (
            [0] => a
        )

)
preg_match_all('/(a|b)(.*?)(\1)/is', 'aabb', $matches);
print_r($matches);
Array
(
    [0] => Array
        (
            [0] => aa
            [1] => bb
        )

    [1] => Array
        (
            [0] => a
            [1] => b
        )

    [2] => Array
        (
            [0] => 
            [1] => 
        )

    [3] => Array
        (
            [0] => a
            [1] => b
        )

)

[ Voor 15% gewijzigd door pimlie op 05-08-2005 15:28 . Reden: shit, te laat.. of eigenlijk te langzaam :( ]