W3docs

Lookahead and Lookbehind

In this chapter, we are going to explore more about finding matches in JavaScript. Learn the convenient ways of using Lookahead and Lookbehind in practice.

Understanding the advanced topics of JavaScript regular expressions is beneficial for any developer looking to enhance their coding skills. Among the more advanced and powerful features within this subject are lookahead and lookbehind assertions. These assertions enable developers to search for patterns in text without including those patterns in the result. This guide aims to provide an in-depth exploration of lookahead and lookbehind assertions in JavaScript, complete with numerous practical examples.

Warning

Regular expressions can be tricky, and edge cases may exist. Especially when you are using advanced concepts like Lookahead and Lookbehind. Use online regex testers or write unit tests to validate your expressions against a variety of input scenarios to ensure they behave as expected.

Introduction to Lookahead and Lookbehind Assertions

Lookahead and lookbehind assertions are zero-width assertions, meaning they match a position within the string rather than actual characters. They allow us to assert whether a given pattern exists or does not exist at a specific point in the string. Note: Modern JavaScript engines (ES2018+) support variable-length lookbehind assertions, though some older environments may require fixed-length patterns.

There are four assertions, formed by combining direction (ahead/behind) with polarity (positive/negative):

AssertionSyntaxMeaning
Positive lookahead(?=...)The pattern must follow this point
Negative lookahead(?!...)The pattern must not follow this point
Positive lookbehind(?<=...)The pattern must precede this point
Negative lookbehind(?<!...)The pattern must not precede this point

Why "zero-width" matters

Because assertions match a position and not characters, the text they check is never included in the match and the regex engine's read position does not advance past it. This is exactly what makes them useful: you can require context around a match without that context becoming part of the result. The snippet below shows the difference between a real capturing group and a lookahead — both verify that pie follows apple, but only the group consumes the text:

javascript— editable

If you are new to the (...) group syntax, see Capturing groups — lookaround uses the same parentheses but adds ?=, ?!, ?<=, or ?<! right after the opening bracket.

Positive Lookahead

A positive lookahead assertion checks for the existence of a certain pattern ahead of the current position in the string. It is denoted by (?=...). The following example is a positive lookahead to find the word "apple" followed by the word "pie":

Javascript regexp lookaround corresponds to characters

javascript— editable

Negative Lookahead

A negative lookahead assertion checks for the absence of a certain pattern ahead of the current position. It is denoted by (?!...). The following example is a negative lookahead to find the word "apple" not followed by the word "pie":

Javascript regexp the negative lookahead

javascript— editable

Positive Lookbehind

A positive lookbehind assertion checks for the existence of a certain pattern behind the current position in the string. It is denoted by (?<=...). Below is a code sample to find the word "pie" that is preceded by the word "apple":

Javascript regexp the positive lookbehind

javascript— editable

Negative Lookbehind

A negative lookbehind assertion checks for the absence of a certain pattern behind the current position. It is denoted by (?<!...). Here is a sample to find the word "pie" that is not preceded by the word "apple":

Lookahead and Lookbehind

javascript— editable

Practical Applications of Lookahead and Lookbehind

Validating Password Strength

Ensuring strong passwords is a common requirement in web applications. Lookahead assertions can be used to validate various password conditions without consuming characters.


javascript— editable

Here every (?=...) is a separate requirement checked from the start of the string. Because each lookahead is zero-width, all four scan the same text independently without interfering with one another, and the final [A-Za-z\d@$!%*?&]{8,} is what actually consumes the password. The ^ and $ anchors pin the check to the whole string, and {8,} is a quantifier requiring at least eight characters.

Formatting and Parsing Data

Lookahead and lookbehind assertions can assist in formatting and parsing complex data structures. A good example is inserting commas into a string of numbers for readability:


javascript— editable

This works by replacing every empty position (\B, a non-word-boundary) that is followed by a group of three digits repeated to the end of the number. The trailing (?!\d) ensures we only match positions where the remaining digits divide evenly into threes, so no comma is placed at the very start.

Extracting the amount from a price

Lookbehind is ideal for grabbing a value that sits after a known marker without capturing the marker itself. Here we pull the numeric amount that follows a $ sign:

javascript— editable

The (?<=\$) lookbehind requires a $ immediately before the number but leaves it out of the result, so each match contains only the figure. Compare this with using a capturing group — a group would force you to read the amount out of match[1], whereas the lookbehind puts the value directly in the match.

Acting only when something does not follow

Negative lookahead lets you act on a position based on what does not come next. This example replaces hello with HI only when it is not followed by world:

javascript— editable

Conclusion

Mastering lookahead and lookbehind assertions in JavaScript can significantly enhance your ability to manipulate and analyze strings. These powerful tools provide the flexibility to assert patterns without consuming characters, making them invaluable for complex text processing tasks. By leveraging these assertions, developers can create more efficient and effective regular expressions, leading to cleaner and more maintainable code.

Practice

Practice
Which of the following statements about lookahead and lookbehind assertions in JavaScript are correct?
Which of the following statements about lookahead and lookbehind assertions in JavaScript are correct?
Was this page helpful?