1

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!

Dion
  • 3,145
  • 20
  • 37
  • Use `/x` modifier with such long regexpes. It will make them way more readable. – Konrad Borowski Apr 04 '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 04 '12 at 19:25
  • 1
    `/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`)). – Konrad Borowski Apr 04 '12 at 19:27
  • Okay, thanks for the information. Good to know this modifier. – Dion Apr 04 '12 at 19:45
  • possible duplicate of [php regex to match outside of html tags](http://stackoverflow.com/questions/7891771/php-regex-to-match-outside-of-html-tags) and [Ignore html tags in preg_replace](http://stackoverflow.com/q/8193327/367456). – hakre Apr 04 '12 at 19:50

2 Answers2

1

What about

$message = preg_replace("/(?i)\b[^\"]((?:htt ...
Eugen Rieck
  • 64,175
  • 10
  • 70
  • 92
  • first I thought it would work, but it doesn't :( Now it works with images but no URLs are replaced – Dion Apr 04 '12 at 19:50
1

UPDATE: Read update below.

Sure. Use negative lookbehind to check what is behind.

The syntax of it is similar to this:

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

For more details see perlre.


UPDATE:

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 <>.

"http://<example.com/img>.png"

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.

Community
  • 1
  • 1
Konrad Borowski
  • 11,584
  • 3
  • 57
  • 71
  • 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 04 '12 at 19:43
  • @DRP96: `(?[`? That doesn't seem to be actual token according to perlre. You have probably forgot `<!`. – Konrad Borowski Apr 04 '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 04 '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. – Konrad Borowski Apr 04 '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 04 '12 at 20:18
  • @DRP96 Perhaps. Regexp engine seems find it forward. This could be more difficult. – Konrad Borowski Apr 04 '12 at 20:23
  • Okay, I did this different now, and its not perfect but it works. – Dion Apr 04 '12 at 20:32