Home > Mobile >  PHP Do not convert between 2 tags
PHP Do not convert between 2 tags

Time:11-06

I have a string. With "pre" tag inside. I don't want to replace the texts in this pre tag. How can I do that?

<?php
$str="
<b>test</b>
<pre>
<b>test</b>
</pre>
<b>test</b>
";
function htmltobb($str){
    $str=preg_replace('(<b>)','[b]',$str);
    $str=preg_replace('(</b>)','[/b]',$str);
    return $str;
}
echo htmltobb($str);
?>

result:

[b]test[/b]
<pre>
[b]test[/b]
</pre>
[b]test[/b]

what i want?

[b]test[/b]
<pre>
<b>test</b> <-- this line not replaced
</pre>
[b]test[/b]

thank you for all answers

CodePudding user response:

A messy approach could be taking everything between pre tags, HTML encoding it, parse everything else, then decode the entities back to characters... this assumes regexs are required and you already have read about their pitfalls.

$str="
<b>test</b>
<pre>
<b>test</b>
</pre>
<b>test</b>
";
echo preg_replace_callback(htmlspecialchars('~(?s)<pre>.*?</pre>~'), function($match) { return htmlspecialchars_decode($match[0]);}, preg_replace('~<(/?)b>~','[$1b]', preg_replace_callback('~(?s)<pre>.*?</pre>~', function($match) { return htmlspecialchars($match[0]);}, $str)));

https://3v4l.org/UZbc2

Start with:

<b>test</b>
<pre>
<b>test</b>
</pre>
<b>test</b>

First run converts to:

<b>test</b>
&lt;pre&gt;
&lt;b&gt;test&lt;/b&gt;
&lt;/pre&gt;
<b>test</b>

Second converts to:

[b]test[/b]
&lt;pre&gt;
&lt;b&gt;test&lt;/b&gt;
&lt;/pre&gt;
[b]test[/b]

Third puts it back as intended:

[b]test[/b]
<pre>
<b>test</b>
</pre>
[b]test[/b]

CodePudding user response:

You need to go cutting your string, do the replace when not inside a pre, and not when yes inside a pre.

$str="
<b>test</b>
<pre>
<b>test</b>
</pre>
<b>test</b>
";

echo htmltobb($str);

function htmltobb($str){    
    $aux = '';
    $posB = 0;
    while (($posA = mb_strpos($str, '<pre>', $posB)) !== false) {
        $aux .= preg_replace(['(<b>)', '(</b>)'], ['[b]', '[/b]'], mb_substr($str, 0, $posA));
        $posB = mb_strpos($str, '</pre>', $posA);
        $aux .= mb_substr($str, $posA, $posB - $posA);
    }
    $aux .= preg_replace(['(<b>)', '(</b>)'], ['[b]', '[/b]'], mb_substr($str, $posB));

    return $aux;
}
  •  Tags:  
  • php
  • Related