Nowadays portable patterns can use negated character classes like ‘[!-aeiou]’. The older syntax ‘[^-aeiou]’ is supported by some shells but not others; hence portable scripts should never use ‘^’ as the first character of a bracket pattern.
Outside the C locale, patterns like ‘[a-z]’ are problematic since they may match characters that are not lower-case letters.