I don't know why, but I just had to try it (even though I don't usually use Perl and had to look up a lot of stuff). I came up with this:

/(?|
    (\()(?&matched)([\}\]”›»】〉》」』]|$) |
    (\{)(?&matched)([\)\]”›»】〉》」』]|$) |
    (\[)(?&matched)([\)\}”›»】〉》」』]|$) |
    (“)(?&matched)([\)\}\]›»】〉》」』]|$) |
    (‹)(?&matched)([\)\}\]”»】〉》」』]|$) |
    («)(?&matched)([\)\}\]”›】〉》」』]|$) |
    (【)(?&matched)([\)\}\]”›»〉》」』]|$) |
    (〈)(?&matched)([\)\}\]”›»】》」』]|$) |
    (《)(?&matched)([\)\}\]”›»】〉」』]|$) |
    (「)(?&matched)([\)\}\]”›»】〉》』]|$) |
    (『)(?&matched)([\)\}\]”›»】〉》」]|$))
(?(DEFINE)(?<matched>(?:
    \((?&matched)\) |
    \{(?&matched)\} |
    \[(?&matched)\] |
    “(?&matched)” |
    ‹(?&matched)› |
    «(?&matched)» |
    【(?&matched)】 |
    〈(?&matched)〉 |
    《(?&matched)》 |
    「(?&matched)」 |
    『(?&matched)』 |
    [^\(\{\[“‹«【〈《「『\)\}\]”›»】〉》」』]++)*+))
/sx;

If the pattern matches, there is a mismatched bracket. $1 is set to the mismatched opening bracket. $-[1] is its location. $2 is the mismatched closing bracket or '' if the bracket was never closed. $-[2] is set to the location of the closing bracket or the end of the string if the bracket wasn't closed.


I didn't write all that manually; it was generated with this:

my @open = ('\(','\{','\[','“','‹','«','【','〈','《','「','『');
my @close = ('\)','\}','\]','”','›','»','】','〉','》','」','』');

'(?|'.join('|',map {'('.$open[$_].')(?&matched)(['.join('',@close[0..($_-1),($_+1)..$#close]).']|$)'} (0 .. $#open)).')(?(DEFINE)(?<matched>(?:'.join('|',map {$open[$_].'(?&matched)'.$close[$_]} (0 .. $#open)).'|[^'.join('',@open,@close).']++)*+))'
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to