regex preg_replace breaks when bbcode

96 views Asked by At

I'm creating highlights of the searchwords on the results page.

This is what I use now:

$resmessage = preg_replace ( '/' . preg_quote ( $searchword, '/' ) . "/iu", '<span  class="searchword" >' . $searchword . '</span>', $resmessage );

But when the word is an title name on a attachment is will break the layout.

example text:

test ok /n[attachment=1]test-2.png[/attachment]

The result:

test ok test-2.png" title="test-2.png" rel="lightbox[imagelink2]">  test-2.png" style="max-height:800px;" alt="" />

So I want exclude none character before searchword. What is the regex to do that, I have tried many options.

2

There are 2 answers

5
chris85 On BEST ANSWER

This should do it for you. \s is a white space (tab, new line, or space), + says one or more occurances of a white space character.

<?php
$resmessage = "test ok /n[attachment=1]test-2.png[/attachment]";
$searchword = 'test';
echo preg_replace ( '/' . preg_quote ( $searchword, '/' ) . "\s+/iu", '<span  class="searchword" >' . $searchword . '</span>', $resmessage);

Output:

<span  class="searchword" >test</span>ok /n[attachment=1]test-2.png[/attachment]

You can replace it with whatever you want the second parameter of preg_replace is what you want there. http://php.net/manual/en/function.preg-replace.php

So

echo preg_replace ( '/' . preg_quote ( $searchword, '/' ) . "\s+/iu", '[b]' . $searchword . '[/b]', $resmessage);

would give you

[b]test[/b]ok /n[attachment=1]test-2.png[/attachment]
8
Marcos Dimitrio On

You can do it by using regex backtracking control verbs (the (*SKIP)(*FAIL) part).

This will allow you to match any string that is not inside BBcode (either between tags or the tag name itself):

$searchword = "test";

$resmessage  = "test attachment ok \n[attachment=1]test-2.png[/attachment] test ";
$resmessage .= "[test]test[/test] ok [attachment=1]my-test-2.png[/attachment] test";

$pattern = '/\[.+?\].*?\[\/.+?\](*SKIP)(*FAIL)|' . 
    preg_quote($searchword, '/') . 
    "/iu";

$resmessage = preg_replace(
    $pattern, 
    '<span class="searchword">' . $searchword . '</span>', 
    $resmessage
);

This will return:

<span class="searchword">test</span> attachment ok 
[attachment=1]test-2.png[/attachment] <span class="searchword">test</span> 
[test]test[/test] ok [attachment=1]my-test-2.png[/attachment] 
<span class="searchword">test</span>