ik probeer een script te maken dat een code in de tekst, die tussen [c] en [/c] staat, omzet naar een prijs, die in de database staat.

Tot nu toe heb ik dit

<?php
include('dbconnect.php');
$tekst = 'dit kost [c]dv1[/c]';

preg_match_all('/\[c\](.*?)\[\/c\]/Usi', $tekst, $matches);

if(!empty($matches[1])){
foreach($matches[1] as $o => $code){
$query = mysql_query("SELECT * FROM codes WHERE code = '". $matches. "' LIMIT 1");
if($row = mysql_fetch_array($query)){
$tekst = str_replace($matches[0][$o], $row['price'], $tekst);
}
}
}
echo $tekst;
?>

maar daarmee zet hij de code niet om in de prijs, maar echoed hij "dit kost [c]dv1 [/c]. Waar denk ik verkeerd?
Er zitten twee problemen in je code.

1) De reden dat $tekst niet wordt veranderd, is omdat je in regel 9 de verkeerde variabele gebruikt: $matches in plaats van $code.

2) Deze is subtiel, maar gaat je een heleboel problemen opleveren. Het betreft je reguliere expressie. Die luidt nu:

/\[c\](.*?)\[\/c\]/Usi

Je gebruikt daarin een *? lazy quantifier, maar je gebruikt ook de modifier U die ervoor zorgt dat de greedyness wordt omgekeerd. Oftewel, je maakt de * juist greedy in plaats van lazy. In het codefragment dat je hebt gepost gaat het goed, maar je krijgt problemen als je bijvoorbeeld als input-string hebt:

$tekst = 'dit kost [c]dv1[/c] en iets anders kost [c]dv2[/c].';

In plaats van twee matches ('dv1' en 'dv2') krijg je dan 1 match 'dv1[/c] en iets anders kost [c]dv2'. Niet wat je wilt.

Oplossing: schrap de U. Je krijgt dan de regex /\[c\](.*?)\[\/c\]/si die wél doet wat je wilt.

(In principe zou je ook de ? kunnen weghalen en de U laten staan, maar dat heeft niet mijn voorkeur, omdat U geen standaard regex modifier is.)
Mijn dank is heel groot.

Reageren