To exclude this you can add at the begining of your expression this subpattern:
(?:\[(url|img)](?>[^[]++|[(?!\/\g{-1}))*+\[\/\g{-1}]|\[(?:url|img)=[^]]*+])(*SKIP)(*FAIL)|your pattern here
The goal of this is to try to match the parts you don't want before and forces the regex engine to fail with the backtracking control verb (*FAIL)
. The (*SKIP)
verb forces the regex engine to not retry the substring matched before when the subpattern fails after.
You can find more informations about these features here.
Notice: assuming that you are using PHP for this pattern, you can improve a little bit this very long pattern by replacing the default delimiter /
by ~
to avoid to escape all /
in the pattern and by using the verbose mode (x modifier) with a Nowdoc syntax. Like this you can comment it, make it more readable and easily improve the pattern
Example:
$pattern = <<<'EOF'
~
### skipping url and img bbcodes ###
(?:
\[(url|img)] # opening bbcode tag
(?>[^[]++|[(?!/\g{-1}))*+ # possible content between tags
\[/\g{-1}] # closing bbcode tag
|
\[(?:url|img)= [^]]*+ ] # self closing bbcode tags
)(*SKIP)(*FAIL) # forces to fail and skip
| # OR
### a link ###
(
(?:https?|ftp|irc):// # protocol
[^\s<>()"]+?
(?:
\( [^\s<>()"]*? \) # part between parenthesis
[^\s<>()"]*?
)*
)
(
(?:[]\s<>".!?,]|,|")*
(?:[\s<>()"]|$)
)
~x
EOF;