JavaScript > Regular Expressions > RegExp Patterns > Lookahead and lookbehind
Lookahead and Lookbehind in JavaScript RegExp
Explore the power of lookahead and lookbehind assertions in JavaScript regular expressions. Learn how to match patterns based on what follows or precedes them without including those surrounding characters in the actual match. This allows for highly flexible and precise pattern matching.
Introduction to Lookahead and Lookbehind
Lookahead
and lookbehind
are powerful features in regular expressions that allow you to match patterns based on what comes before or after them, without including the lookahead/lookbehind part in the matched text. They're called 'assertions' because they assert that a certain pattern exists before or after the main pattern you're trying to match.
Positive Lookahead: Matching What Follows
(?=pattern)
is the syntax for positive lookahead. It matches if the pattern
is found after the main pattern. In this example, the regex /Java(?=Script)/
matches 'Java' only if it's followed by 'Script'. The 'Script' part itself isn't included in the matched result. The result will be the 'Java' string. If 'Java' isn't followed by 'Script', then there won't be a match.
const str = 'JavaScript is awesome!';
const regex = /Java(?=Script)/;
const match = str.match(regex);
console.log(match); // Output: ['Java', index: 0, input: 'JavaScript is awesome!', groups: undefined]
Negative Lookahead: Matching What Does Not Follow
(?!pattern)
is the syntax for negative lookahead. It matches if the pattern
is not found after the main pattern. In this example, the regex /Java(?!Script)/
matches 'Java' only if it's NOT followed by 'Script'. Therefore, this will find the 'Java' in the first 'Java' substring. If the string was just 'JavaScript', it would return null.
const str = 'Java is great, but JavaScript is better!';
const regex = /Java(?!Script)/;
const match = str.match(regex);
console.log(match); // Output: ['Java', index: 0, input: 'Java is great, but JavaScript is better!', groups: undefined]
Positive Lookbehind: Matching What Precedes (ES2018+)
(?<=pattern)
is the syntax for positive lookbehind. It matches if the pattern
is found before the main pattern. It was introduced in ES2018. In this example, the regex /(?<=USD )\d+/
matches one or more digits (\d+
) only if they are preceded by 'USD '. The result includes only the digits, not 'USD '.
const str = 'USD 100, EUR 50';
const regex = /(?<=USD )\d+/;
const match = str.match(regex);
console.log(match); // Output: ['100', index: 4, input: 'USD 100, EUR 50', groups: undefined]
Negative Lookbehind: Matching What Does Not Precede (ES2018+)
(? is the syntax for negative lookbehind. It matches if the
pattern
is not found before the main pattern. It was introduced in ES2018. In this example, the regex /(? matches one or more digits (
\d+
) only if they are NOT preceded by 'USD '. Therefore, this will find the '50' string.
const str = 'USD 100, EUR 50';
const regex = /(?<!USD )\d+/;
const match = str.match(regex);
console.log(match); // Output: ['50', index: 17, input: 'USD 100, EUR 50', groups: undefined]
Real-Life Use Case: Validating Passwords
Lookaheads are extremely useful for validating password complexity. This example checks for uppercase letters, lowercase letters, numbers, special characters, and a minimum length, all using lookaheads. The multiple lookaheads allow you to assert all requirements are met without consuming the string. Each check does not move forward to the next character, but verifies a condition.
function validatePassword(password) {
const hasUpperCase = /(?=.*[A-Z])/;
const hasLowerCase = /(?=.*[a-z])/;
const hasNumber = /(?=.*\d)/;
const hasSpecialChar = /(?=.*[^a-zA-Z0-9\s])/;
const isLongEnough = /^.{8,}$/;
return (
hasUpperCase.test(password) &&
hasLowerCase.test(password) &&
hasNumber.test(password) &&
hasSpecialChar.test(password) &&
isLongEnough.test(password)
);
}
console.log(validatePassword('P@ssword123')); // Output: true
console.log(validatePassword('Password')); // Output: false
Best Practices
When to Use Them
Use lookahead/lookbehind when you need to match a pattern based on its context (what's before or after it) without including the surrounding context in the match. This is particularly useful for validation, parsing, and complex text manipulation tasks.
Alternatives
While lookahead/lookbehind are powerful, sometimes you can achieve similar results with capturing groups and string manipulation. However, this often involves more code and can be less efficient, especially for complex patterns. You can also use multiple regular expressions combined to achieve the result.
Pros
Cons
FAQ
-
What's the difference between lookahead and lookbehind?
Lookahead checks what's after the main pattern, while lookbehind checks what's before the main pattern. Both are assertions that don't include the matched surrounding text in the final result. -
Are lookbehind assertions supported in all browsers?
No, lookbehind assertions were introduced in ES2018 and may not be supported in older browsers. Always check browser compatibility before using them in production. -
Can I use lookaheads and lookbehinds together in the same regular expression?
Yes, you can combine lookaheads and lookbehinds to create very specific and powerful matching conditions. However, ensure the complexity doesn't impact readability or performance.