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;