I started off referring to the Perl Black Book (my reference of choice) but when back to the camel book to find my edition is some six years old (amazing the number of things added to regex since perl5 first came out, there were no lookbehind assertions then). Here's something from the good, solid, continually updating perldoc.com resource:
It goes through everything pretty well.
In short, the x param at the end ignores whitespace and lets you add line comments with # If you explicitly want whitespace, you have to escape it. It just lets you split the regex up into multiple lines, easier readability and commenting.
The (?(?! business is two things:
(?! pattern) is a negative look ahead assertion. It scans ahead to see if what's there would (or in this case, wouldn't, hence the negating !) match. They key is that it doesn't consume what was matched, it leaves it match pointer, or whatever it's called, before that. Positive lookahead is (?= pttn), and +/- lookbehind is (?<=) / (?<!). I think I'm not making much sense here, so check the link, they're better at this than I.
(?(condition)pattern true|pattern false) I'll just quote perldoc on this one: "Conditional expression. (condition) should be either an integer in parentheses (which is valid if the corresponding pair of parentheses matched), or lookahead/lookbehind/evaluate zero-width assertion."
And the syntax errors...well, I will say this: if there is no [notag] block to match, $2 will be empty since its in the conditional block, and since $1 collects everything between the opening [$tag] and opening [notag], $3 is empty as well. I had warnings on, but not the strict pragma, so it spat back "Use of uninitialize value in concatentation or string". I don't think strict would have any problems with this either, now that I think about. Dunno. ----------------------------------------------------------------------------------
...but I'm just a C man trying to see the light