Reputation: 75
Is there a way to replace tags only if there are both open and close for example:
//search to replace
$text = '[b]this will be bold[/b] but this will be not.';
$search = array('[b]long string[/b]');
//replace with
$replace = array('<b>long string</b>');
echo str_replace($search, $replace, $text);
wanted Result:
this will be bold but this will be not.
I'm not sure how to set it up correctly any help will be thankful.
Upvotes: 3
Views: 1490
Reputation: 14390
I've write for you advanced BBcode parse function
you can add any BBcode inside $tags = 'b|url';
for example
$tags = 'b|url|i|e|img';
also its support bbcode with inner tags for example [url=http://www.website.com]blaa[/url]
this is the full code
function parseBBCODE($text)
{
//bbcodes tags
$tags = 'b|url';
//loop tags sub tags too
while (preg_match_all('#\[('.$tags.')=?(.*?)\](.+?)\[/\1\]#is',$text, $matches))
foreach ($matches[0] as $key => $match)
{
//extract tag info
list($tag, $param, $innertext) = array($matches[1][$key], $matches[2][$key], $matches[3][$key]);
//match tags and replace them
switch ($tag)
{
//Bold
case 'b':
$replacement = '<b>'.$innertext.'</b>';
break;
//link url
case 'url':
$replacement = '<a target="_blank" href="'.($param ? $param : $innertext).'">'.$matches[3][$key].'</a>';
break;
default :
$replacement = "";
}
$text = str_replace($match, $replacement,$text);
unset($match,$replacement,$param);
}
return $text;
}
$search = '[b]long string [/b] [url]http://www.google.com[/url] [url=http://www.google.com]url with tag[/url]';
echo parseBBCODE($search);
Upvotes: 1
Reputation: 1215
It sounds like you want to implement a system of BBCodes, which you'll need to use regular expressions to do.
There's a very good article at http://thesinkfiles.hubpages.com/hub/Regex-for-BBCode-in-PHP which explains how to do this with explanations of what the various regex parts mean so that you can write your own additions later on.
The code to convert your example above on its own however is as follows:
$text = '[b]this will be bold[/b] but this will be not.';
$ret = $text; // So we don't overwrite the original variable.
$ret = preg_replace('#\[b\](.+)\[\/b\]#iUs', '<b>$1</b>', $ret);
Upvotes: 3
Reputation: 44833
Something like this will do it:
//search to replace
$text = '[b]this will be bold[/b] but this will be not.';
$search = array('~\[([^]]+)\]([^][]*)\[/\1\]~');
//replace with
$replace = array('<$1>$2</$1>');
echo preg_replace($search, $replace, $text);
Output:
<b>this will be bold</b> but this will be not.
There's a PHP demo here.
Regex demo and explanation:
\[([^]]+)\]([^][]*)\[/\1\]
Caveat emptor: this is very simplified and ignores some serious safety issues. In reality, you must account for things like disallowing <script>
, <iframe>
, and other tags that could lead to cross-site scripting injections.
As always with this kind of thing, a parser is likely to beat regex.
If you really want to use regex: replace ([^]]+)
with a whitelisted group of tags. Example:
\[(b|em|i|strong)\]([^][]*)\[/\1\] // allows only b, em, i, and strong
Upvotes: 2
Reputation: 160833
You could use a regex to do this:
$text = '[b]this will be bold[/b] but this will be not.';
$text = preg_replace('/\[([a-z]+)\](.*?)\[\/\1\]/', '<\1>\2</\1>', $text);
Upvotes: 1