I'm using preg_replace to convert all BBCode to HTML but can't get img tags to work. Here is my code:
$search = array (
'/(\[b\])(.*?)(\[\/b\])/m',
'/(\[i\])(.*?)(\[\/i\])/m',
'/(\[u\])(.*?)(\[\/u\])/m',
'/(\[ul\])(.*?)(\[\/ul\])/m',
'/(\[li\])(.*?)(\[\/li\])/m',
'/(\[user=)(.*?)(\])(.*?)(\[\/user\])/m',
'/(\[url=)(.*?)(\])(.*?)(\[\/url\])/m',
'/(\[url\])(.*?)(\[\/url\])/m',
'/(\[img=)(.*?)(\])(.*?)(\[\/img\])/m',
'/(\[quote\])(.*?)(\[\/quote\])/m',
'/(\[code\])(.*?)(\[\/code\])/m',
);
$replace = array (
'<strong>$2</strong>',
'<em>$2</em>',
'<u>$2</u>',
'<ul>$2</ul>',
'<li>$2</li>',
'<a href="../login/profile?u=$2" target="_blank">$2</a>',
'<a href="$2" target="_blank">$4</a>',
'<a href="$2" target="_blank">$2</a>',
'<img src="$4"></img>',
'<quote>$2</quote>',
'<code>$2</code>'
);
$string = preg_replace($search, $replace, $string);
Right now it creates an image tag with the link in but adds ]
to the start and end of the link so it doesn't display the image correctly.
EDIT:
This is cause by me converting links to anchor tags and it's conflicting within the [img] BBCode.
$url = '/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/';
$string = preg_replace($url, '[url=$0]$0[/url]', $string);
Several points to make:
/
to ~
so that you don't have to escape the /
characters that exist inside your pattern.]
to be the end of a character class if a character class is opened. For this reason, I am not escaping any ]
characters.^
or $
), the m
pattern modifier is needless.i
pattern flag/modifier.$1
in the replacement string.(*SKIP)(*FAIL)
"disqualifies" these unwanted substrings.Code: (Demo)
$bbcodes = [
'Look at this:https://www.example.com/example?ohyeah=sure#okay this is a raw link',
'No attibute bbcode url: [url]http://example.com/x1[/url]',
'A url with link and link text: [url=http://example.com/x2]x2[/url]',
'Image with "ignorable" text: [IMG=sumpthing.jpg]sumpthing[/IMG]',
'Image: [img=sumpinelse][/img]'
];
$search = array (
// ...
'~\[url=((?:ht|f)tps?://[a-z\d.-]+\.[a-z]{2,3}/\S*?)](.*?)\[/url]~i',
'~\[url]((?:ht|f)tps?://[a-z\d.-]+\.[a-z]{2,3}/\S*?)\[/url]~i',
// ...
'~\[img=(.*?)].*?\[/img]~i', // if you want the possibility of dot matching newlines, add s pattern modifier
// ...
'~(?:<a.*?</a>|<img.*?</img>)(*SKIP)(*FAIL)|\bhttps?://.+?(?=\s|$)~im' // mop up any remaining links that are not bbtagged
);
$replace = array (
// ...
'<a href="$1" target="_blank">$2</a>',
'<a href="$1" target="_blank">$1</a>',
// ...
'<img src="$1"></img>',
// ...
'<a href="$0" target="_blank">$0</a>',
);
var_export(preg_replace($search, $replace, $bbcodes));
Output:
array (
0 => 'Look at this:<a href="https://www.example.com/example?ohyeah=sure#okay" target="_blank">https://www.example.com/example?ohyeah=sure#okay</a> this is a raw link',
1 => 'No attibute bbcode url: <a href="http://example.com/x1" target="_blank">http://example.com/x1</a>',
2 => 'A url with link and link text: <a href="http://example.com/x2" target="_blank">x2</a>',
3 => 'Image with "ignorable" text: <img src="sumpthing.jpg"></img>',
4 => 'Image: <img src="sumpinelse"></img>',
)