Take the 2-minute tour ×

I have a little problem with some preg_replace functions in PHP. First I have $message = preg_replace("/\[img\](.*?)\[\/img\]/is", '<img src="$1" alt="" />', $message); for replacing [img]http://example.com/img.png[/img] with an image. But after that I also have a preg_replace which replaces URLs:

$message = preg_replace("/(?i)\b((?:https?:\/\/|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'\".,<>?«»“”‘’]))/", '<a href="$1">title[$1]</a>', $message);

Is it possible to prevent that the URL within <img src='' is also replaces with a link? Like putting the URL replace function before the img preg_replace and changing the pattern that it won't change URLs which are within BB-Code brackets?

Thanks for answers!

share|improve this question
Use /x modifier with such long regexpes. It will make them way more readable. –  xfix Apr 4 '12 at 19:20
Thanks for your quick answer, Sorry but what do you mean by /x modifier? And what would that make more readable and how? –  Dion Apr 4 '12 at 19:25
/x modifier allows to use comments and spaces inside regexpes, without triggering any special stuff. I always make regexpes with this, but technically, it's just a small thing to make code like this more readable :). Too bad you cannot use /x in JavaScript :(, but you can in PHP (and it's good idea, unless you have very simple regexp (Perl Best Guidelines sets that limit to 0, but you can of course choose when to use /x)). –  xfix Apr 4 '12 at 19:27
Okay, thanks for the information. Good to know this modifier. –  Dion Apr 4 '12 at 19:45
possible duplicate of php regex to match outside of html tags and Ignore html tags in preg_replace. –  hakre Apr 4 '12 at 19:50
add comment

2 Answers

up vote 1 down vote accepted

UPDATE: Read update below.

Sure. Use negative lookbehind to check what is behind.

The syntax of it is similar to this:

# Match abc if there is no ' or " behind
(?<!['"]) abc

For more details see perlre.


It seems that it doesn't really work. The trick literally means no ' or " behind, so regexp actually sees something like this (where matched string is in <>.


Instead of using this trick, you should read Ignore html tags in preg_replace instead. Sometimes regexp is not solution and that's one of those cases.

share|improve this answer
Hm, I changed it now to /(?[\]])\b((?:https?:\/\/| at the beginning but theres always an error: preg_replace() [function.preg-replace]: Compilation failed: unrecognized character after (? at offset 2 in [...] –  Dion Apr 4 '12 at 19:43
@DRP96: (?[? That doesn't seem to be actual token according to perlre. You have probably forgot <!. –  xfix Apr 4 '12 at 19:52
So it would be (?<![\]\[])? That doesn't work either.. How would it be in my case (that no [ or ] is in front or after the expression)? –  Dion Apr 4 '12 at 20:04
@DRP96, what exactly you're trying to do? This tries to find ] or [ and fails if it will be found. As for after, use negative lookforward, for example (?<![\]\[])...(?![\]\[]) where ... is your code. –  xfix Apr 4 '12 at 20:14
Thats really stupid. Now I used your example and [IMG]http://example.com/img.png[/IMG] returns [IMG]http://. Could this be caused by the expression? –  Dion Apr 4 '12 at 20:18
show 2 more comments

What about

$message = preg_replace("/(?i)\b[^\"]((?:htt ...
share|improve this answer
first I thought it would work, but it doesn't :( Now it works with images but no URLs are replaced –  Dion Apr 4 '12 at 19:50
add comment

Your Answer


