Ik heb een preg_replace pattern dat alleen de woorden vervangt in een tekst die tussen <p> en </p> staat. Dat werkt goed. Alleen iets te goed. Het probleem wat ik nu heb is dat ik alleen een geheel woord wil vervangen als die voorkomt en niet een deel van een woord.

Voorbeeld: het woord "strand" wordt vervangen in de tekst voor een link. Maar ook een deel van het woord "zandstrand" wordt vervangen en komt er uit te zien als: zand<a href="#">strand</a>. Het woord "zandstrand" zou in dit geval genegeerd moeten worden.

<?php
foreach ($keywords as $word => $link) {
  $pattern = '|^(<p[^>]*>.*)('. preg_quote($word, '|') .')(.*</p>)$|mui';
  $replace = '$1<a href="'. site_url() .'/tag/'. $link .'/">$2</a>$3';
  $content = preg_replace($pattern, $replace, $content);
}
?>


Heeft er iemand de oplossing?

Volgens mij moet je een /b aan het einde van je reg-ex plaatsen. Dit is een boundary die ervoor zorgt dat er exact gematched wordt met het hele woord.
Dat idee had ik ook al, maar waar ik dit ook plaats. Het probleem blijft of wordt zelfs erger. Als ik hier $pattern = '|^(<p[^>]*>.*)('. preg_quote($word, '|') .')(.*</p>)$|mui/b'; van maak, dan verdwijnt de hele content. Of doe ik dit nu verkeerd?
Hoe ziet je pattern er nu uit volgens $pattern?
Dit is de volledige code


<?php
foreach ($keywords as $word => $link) {
  $pattern = '|^(<p[^>]*>.*)('. preg_quote($word, '|') .')(.*</p>)$|mui';
  $replace = '$1<a href="'. site_url() .'/tag/'. $link .'/">$2</a>$3';
  $content = preg_replace($pattern, $replace, $content);
}
?>


Bij deze code verdwijnt de hele $content


<?php
foreach ($keywords as $word => $link) {
  $pattern = '|^(<p[^>]*>.*)('. preg_quote($word, '|') .')(.*</p>)$|mui/b';
  $replace = '$1<a href="'. site_url() .'/tag/'. $link .'/">$2</a>$3';
  $content = preg_replace($pattern, $replace, $content);
}
?>
Het is even geleden dat ik daarmee gespeeld heb, maar volgens mij moest je de string tussen \b en \b zetten.

Laat anders even een voorbeeld van je (geparste) pattern zien. Dan kan je meteen via https://regexper.com/ deze uittesten.
Ik heb het probleem op kunnen lossen mede dankzij je tip. Ik heb het pattern wat aangepast en dit was de oplossing:
$pattern = '/^(<p[^>]*>.*)\b('. preg_quote($word, '|') .')\b(.*<\/p>)$/imu';
Let op dat je in je $pattern nu de "/" als delimiter gebruikt, maar in preg_quote() nog steeds de "|" meegeeft.
(persoonlijk geef ik de voorkeur aan "/", omdat je je regex-en dan redelijk naadloos naar javascript-land kunt meenemen).
Rob Doemaarwat op 25/02/2018 14:15:52
(persoonlijk geef ik de voorkeur aan "/", omdat je je regex-en dan redelijk naadloos naar javascript-land kunt meenemen).


En het #-teken? Wellicht is dat nog beter als delimiter?
In PHP is het #-teken misschien handiger? Regexen portable houden, weet niet of dat echt zinnig is?
@Thomas: Meestal voor (ook) client-side validatie (als extra stukje service naar de gebruiker toe).

Reageren