I am specifically looking for something like NOT b
in the expression... I know something like /[ac-z]/
will work but I'm looking something like /[a-z&[^b]]
which says match a-z
and without b
...
Someone suggested /[a-z&&[^b]]/
but the engine takes the [
after &
as a character instead of bracket expression.
CodePudding user response:
You could use a negative lookahead at the start of the pattern. For example:
^(?!.*b)[a-z] $
This matches any lowercase letter except for b
. The (?!.*b)
is a negative lookahead which asserts that b
cannot be found anywhere in the string. So while [a-z]
does include b
, if the pattern gets this far b
has already been ruled out.
CodePudding user response:
There are several ways to test for a
to z
without b
.
1. Gap in character class
Use as a gap in the character class: ^[ac-z] $
. Note that the pattern uses ^
and $
to anchor the string at the beginning and end. This avoids false positives like %xyz123
.
[ 'abcd', 'xyz' ].forEach(str => {
console.log(str, '==>', /^[ac-z] $/.test(str));
});
2. Negative lookahead
Use a negative lookahead as Tim Biegeleisen stated: ^(?!.*b)[a-z] $
. Please note that lookahead/lookbehind is not supported by all browsers, notably Safari.
[ 'abcd', 'xyz' ].forEach(str => {
console.log(str, '==>', /^(?!.*b)[a-z] $/.test(str));
});
3. Logical or
Use a non-capture group with logical or
: ^(?:a|[c-z]) $
[ 'abcd', 'xyz' ].forEach(str => {
console.log(str, '==>', /^(?:a|[c-z]) $/.test(str));
});
4. Multiple regexes
Sometimes it helps using more than one regex with logical combinations, such as A || B && !C
. This is mainly useful in more complex situations.
[ 'abcd', 'xyz' ].forEach(str => {
console.log(str, '==>', /^[a-z] $/.test(str) && !/b/.test(str));
});
Learn more about regex: https://twiki.org/cgi-bin/view/Codev/TWikiPresentation2018x10x14Regex