Two completely different meanings of ^
The caret has TWO meanings depending on context. This trips up everybody at some point.
- Outside a character class:
^is the start-of-string anchor. - Inside a character class, as the first character:
^negates the class. - Inside a character class, NOT as the first character:
^is literal.
So ^[abc] means "start of string, then an a, b, or c."
And [^abc] means "any character that's not a, b, or c."
And [a^b] means "a, literal caret, or b."
The bug class this creates
The most common bug: writing ^[abc] when you meant [^abc]. The first matches "a/b/c at the start of the string" — only matches one character. The second matches "anything except a/b/c" — anywhere.
When debugging a pattern that's behaving wrong, look at every ^ and ask: "Am I inside or outside square brackets? And is it position 1?"
The same is true for $ — but less confusing
$ has only one meaning (end-of-line/string). It's never special inside a character class. [a$b] is just "a, dollar sign, or b." No surprise.