When you define a negative character class, you are really inverting it.
What does that mean ?
A positive character class implicitly OR's it's contents.
When you negate a class, you implicitly AND it's contents.
So, [\w-]
means word OR dash
,
the inverse, [^\w-]
means not word AND not dash
.
A negative word for instance, [^\w]
would match a dash -
.
So, to not match it, you have to add a not dash
as well.
A C analogy would be
existing (varA || varB)
inverted (!varA && !varB)
where inverting changes the Boolean of each of the components.
Basically a negative class changes the Boolean of each of its components,
so the implicit OR becomes an implicit AND and the components characters
(or expressions) are negated.
What will really bake your noodle later on is when you see something like
[^\S\r\n]
This translates to NOT-NOT-Whitespace
and NOT-cr
and NOT-lf
which reduces to matching all whitespace except CR,LF