2

I've tried many ways to do this, the only one which seems to partially do what I want is the lookahead negation described in String negation using regular expressions and How to negate specific word in regex? but I can't get it to work with my current regex.

Assuming I have this string:

[url=http://www.example.com]this url BB tag should match[/url]
[url=http://www.example.com][spoiler]this url BB tag shouldn't match[/spoiler][/url]

Edit: More in-depth string which shouldn't return a match for debugging:

[url=http://www.example.com]Lorem[spoiler]this url BB tag shouldn't match[/spoiler]Ipsum[/url]

And the current regex pattern:

#\[url=([\w]+?://.*?)\]([^?\n\r\t].*?)\[/url\]#is

Edit: I'm using the following regex (without # and #is) to debug it on Regex Buddy:

\[url=([\w]+?://.*?)\]([^?\n\r\t].*?)\[/url\]

(these 2 regex should have the same effect on my application as I can easily adapt it, so work with the latter if it makes more sense)

Will match both lines in the string. I want it to don't return a match when there's a [spoiler] string between the [url=xxxx://yyyy] and [/url].

I think it can be done with the negative lookahead but I can't seem to find a way to insert it in the current regex without turning it unusable.

Any help is appreciated.

Community
  • 1
  • 1
Fabrício Matté
  • 69,329
  • 26
  • 129
  • 166

1 Answers1

1

This should solve the problem.

'#\[url=([^\]]+)\](?!\[spoiler\])(.*?)\[/url\]#'
Rezigned
  • 4,901
  • 1
  • 20
  • 18
  • It's still returning a match for `[url=http://www.google.com][spoiler][/spoiler][/url]` on my php and regex testers. – Fabrício Matté Apr 18 '12 at 03:40
  • Here's my test `preg_match('#\[url=([^\]]+)\](?!\[spoiler\])(.*?)\[/url\]#', '[url=http://www.google.com][spoiler][/spoiler][/url]', $m); print_r($m);` It returns nothing tho (which is what you want). – Rezigned Apr 18 '12 at 03:55
  • Oh sorry, for my comment above it actually doesn't return a match for your regex, however, if I add any character before the `[spoiler]` it'll return a match: `[url=http://wwww.google.com]Hi[spoiler][/spoiler][/url]` – Fabrício Matté Apr 18 '12 at 03:55
  • Adding a .* inside the lookahead seems to do the trick, I'll debug it and post results. – Fabrício Matté Apr 18 '12 at 04:03
  • 1
    Alright, `(?!.*\[spoiler\])` lookahead does the trick, but I still wanted to keep the \w iteration and :// check for this pattern, so here's the final regex: `#\[url=(?=[^_\W]+?://)([^\]]+)\](?!.*\[spoiler\])(.*?)\[/url\]#i`. Thanks for the help. – Fabrício Matté Apr 18 '12 at 08:45
  • Oh I found an exception, `[url=xxxx://yyyy]zzzz[/url][spoiler][/spoiler]` wouldn't return any match with the regex above, here is the fixed version if anyone ever gets into a similar problem while editing a phpbb2 pattern: `#\[url=(?=[^_\W]+?://)([^\]]+)\](?!.*?\[spoiler\].*?\[/url\])(.*?)\[/url\]#i` – Fabrício Matté Apr 18 '12 at 09:07