Reputation: 42773
I have this script for replacing BBCODE image tags to HTML tags
$text = "[img]https://somelink/2/3/pic.jpg[/img]
[img]https://somelink/2/3/pic.jpg[/img]
[img]https://somelink/2/3/pic.jpg[/img]";
echo preg_replace(
'~\[img\](https?://.*?\.(?:jpg|jpeg|gif|png|bmp))\[/img\]~s',
'<img src="$1" alt="" />',
$text);
This forks for links, which ends up whit some of given extensions: .jpg
.jpeg
...
But if link are like: [img]https://somelink/2/3/pic.jpg
?w=bla[/img]
Then this regex pattern fails.
What would be appropriate pattern for all type of image links? I tried:
~\[img\](https?://.*?\.(?:jpg|jpeg|gif|png|bmp).*)\[/img\]~Us
But this also not works
Upvotes: 0
Views: 111
Reputation: 163362
If it is possible that the query string parameters can also contain [
or ]
you could match the question mark \?
followed by matching until you encounter [/img]
and make use of a possessive quantifier to prevent unnecessary backtracking
Explanation
\[img\](https?://.*?\.(?:jpe?g|gif|png|bmp)(?:\?(?:[^[]++|\[(?!/img\]))*+)?)\[/img]
\[img\]
Match [img]
(
Capturing group
https?://.*?
Match http with optional s, ://
and 0+ times any char non greedy\.(?:jpe?g|gif|png|bmp)
Match a dot and any of the listed options(?:
Non capturing group
\?
Match ? (?:[^[]++|\[(?!/img\]))*+
Repeat 0+ times matching not [
or match [
when what is directly on the right is not /img]
)?
Close non capturing group and make it optional)
Close capturing group\[/img]
Match [/img]
Upvotes: 1
Reputation: 37755
You can use
\[img\](https?://.*?\.(?:jpe?g|gif|png|bmp).*?)\[/img\]
\[img\]
- Matches [img]
(https?://.*?\.(?:jpe?g|gif|png|bmp).*?)
- Matches URL containing any of above extensions\[/img\]
- Matches [/img]
You can visualize regex here
Note:- as you're using U
flag you can safely remove ?
after quantifiers, i.e
\[img\](https?://.*\.(?:jpe?g|gif|png|bmp).*)\[/img\]
Upvotes: 1