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
