Alle img src in een string aanpassen.
Ik heb binnen een website die ik beheer voor een basisschool het volgende probleem.
De leraren en leraressen willen meerdere foto's tegelijk op een "eigen" pagina laten zien.
Ze zijn in kennis echter beperkt en de meeste kunnen (willen) die foto's niet comprimeren of verkleinen. Ik krijg dus 10-tallen foto's van zo'n 3mb tot 7mb per stuk binnen die op de site moeten komen, verwerkt in een verhaal.
Ik heb besloten om phpThumb() te gaan gebruiken i.c.m. Fancybox.
Fancybox werkt goed.
phpThumb() werkt ook goed, mits ik de afbeelding handmatig toevoeg.
Probleem is dat de foto's d.m.v. een tekst editor toegevoegd worden aan het verhaal en opgeslagen worden in een mysql database.
Ik moet dus nu op een of andere manier voor elkaar zien te krijgen dat ALLE <img src> in de string gevonden worden en aangepast zodat phpThumb() ze kan verwerken.
Na lang zoeken op internet lijkt regexp de methode te zijn.
Dit is nu net iets waar ik de ballen van begrijp. Dus is er misschien iemand die mij kan uitleggen hoe ik dit ga oplossen?
De code die ik nu heb gevonden is de volgende:
Code (php)
1
2
3
4
5
2
3
4
5
<?php
$regex = "-(<img[^>]+src\s*=\s*['\"])((?:(?!'|\"|http://).)*)(['\"][^>]*>)-i";
$tekst = preg_replace($regex, "$1scripts/phpThumb/phpThumb.php?src=$2&h=150&hash=xxxxxxxxxxxx$4", $res['tekst']);
echo $tekst;
?>
$regex = "-(<img[^>]+src\s*=\s*['\"])((?:(?!'|\"|http://).)*)(['\"][^>]*>)-i";
$tekst = preg_replace($regex, "$1scripts/phpThumb/phpThumb.php?src=$2&h=150&hash=xxxxxxxxxxxx$4", $res['tekst']);
echo $tekst;
?>
Wat houdt de regex in? is geheel abracadabra voor mij.
Waar komen de $1, $2 en $4 variabelen vandaan en wat betekenen ze?
En.. Waarom werkt het niet?
Is er iemand die mij een juiste werkende code kan geven, of iemand die mij dit duidelijk kan uitleggen zodat ik het zelf kan oplossen?
Bij voorbaat dank.
Goeny
Met behulp van zo'n handig tooltje (http://www.regexr.com/) heb ik nu een regexp in elkaar weten te knutselen welke precies vind wat ik nodig heb.
Volgens het tooltje heb ik ook alles netjes in groepen die ik terug zou moeten plaatsen.
Mijn huidige code is:
Code (php)
1
2
3
4
2
3
4
<?php
$regex = '(<img(.*?)src=")(.*?)(".*?\>)';
$tekst = preg_replace($regex, '$1scripts/phpThumb/phpThumb.php?src=$3&h=150&hash=xxxxxx$4', $res['tekst']);
?>
$regex = '(<img(.*?)src=")(.*?)(".*?\>)';
$tekst = preg_replace($regex, '$1scripts/phpThumb/phpThumb.php?src=$3&h=150&hash=xxxxxx$4', $res['tekst']);
?>
Het is dus de bedoeling dat uit mijn tekst alle <img src= worden aangepast.
Voorbeeld:
<img alt="" src="http://www.domein.org/userfiles/Groepen/groep4-5/IMAG0008[1].jpg" style="width: 268px; height: 150px; margin: 3px; float: left;">
Zou moeten worden:
<img alt="" src="scripts/phpThumb/phpThumb.php?src=http://www.domein.org/userfiles/Groepen/groep4-5/IMAG0008[1].jpg&h=150&hash=xxxxxx" style="width: 268px; height: 150px; margin: 3px; float: left;">
Zoals gezegd... het tooltje geeft aan dat mijn regexp klopt en matches vindt. Ook staan deze in groepen.
Maar toch werkt het niet... Wat doe ik fout?!
Daarbij vergeet je ook de delimiters:
maar ik zou het zo doen:
Code (php)
1
2
3
4
5
2
3
4
5
<?php
$regex = '~<img(.*)src="([^"]+)"([^?]+)>~';
$tekst = preg_replace($regex, '<img $1 src="scripts/phpThumb.php?src=$2&h=150"', $res['tekst']);
?>
$regex = '~<img(.*)src="([^"]+)"([^?]+)>~';
$tekst = preg_replace($regex, '<img $1 src="scripts/phpThumb.php?src=$2&h=150"', $res['tekst']);
?>
Jouw regex breekt als er in een string twee img tags voorkomen. In dat geval is het juist belangrijk om je quantifier ungreedy te maken met een ?
Een ander voordeel is dat bij een ungreedy quantifier je regex parser niet hoeft te backtracken, wat in sommige gevallen een snelheidswinst kan opleveren.
Ineens werkte het script goed.
Nu zit ik met het volgende probleem en dat is een 403 error.
Ik ga er even mee klooien, zal wel iets met permissies zijn.
Bedankt voor de hulp!
Nieuw toetsenbord is nog even wennen:
die [^?] had een [^>] moeten zijn: alles, zolang het geen > is pakken.
Dat is in principe dus ook een soort van ungreedy,
Ik doelde eigenlijk op:
img(.*)src
Daar zou ik zelf
img(.*?)src
hebben gebruikt.
Je noemt [^>]+ een "soort van ungreedy", maar dat ding is zo greedy als maar zijn kan. Het eindresultaat is weliswaar hetzelfde als dat van een lazy quantifier, maar het pad ernaartoe is anders. Door de + zal de regex eerst een zo lang mogelijke string matchen en vervolgens moet hij de hele match backtracken om te kijken of er geen > in voorkomt. Dat is alleen maar efficiënt als de img-tag de enige tag in de input is. Als je echter een hele HTML-pagina als input hebt, moet de regex dus voor elke img-tag het gehele restant van de input teken voor teken backtracken.