Regular expressions are powerful because they consume characters left-to-right. But what happens when you need to check if a character exists without actually consuming it?
Enter Zero-Width Assertions, commonly known as Lookaheads and Lookbehinds.
They are called "zero-width" because they match a position in the string, rather than the characters themselves. They act like a boolean true/false check that the regex engine runs before deciding whether to proceed.
1. Positive Lookahead `(?=...)`
A positive lookahead tells the engine: "Look to the right of your current position. Does this pattern exist? If yes, continue. But DO NOT move your position."
Use Case: Match the word "JavaScript" but only if it is followed by the word "Developer".
```regex
JavaScript(?=\sDeveloper)
```
How the Engine Reads It:
- The engine finds "JavaScript".
- Its current position is right after the 't'.
- The lookahead
(?=\sDeveloper)peeks to the right. It sees a space and "Developer". - The lookahead returns
true. - The match is successful, but the final extracted match is ONLY "JavaScript". The word "Developer" is not consumed.
2. Negative Lookahead `(?!...)`
A negative lookahead tells the engine: "Look to the right. Ensure this pattern DOES NOT exist here."
Use Case: Match the word "apple" but only if it is NOT followed by " pie".
```regex
apple(?!\spie)
```
In the test string, "apple juice" matches because the lookahead checks for " pie", doesn't find it, returns true, and proceeds. "apple pie" fails.
3. Positive Lookbehind `(?<=...)`
A positive lookbehind tells the engine: "Look to the LEFT of your current position. Did this pattern just happen?"
Use Case: Extract the price value, but only if it is preceded by a dollar sign.
```regex
(?<=$)[0-9]+
```
How the Engine Reads It:
- The engine scans the string.
- The lookbehind
(?<=\$)checks the character before the current position. Is it a$? - If yes, it returns
true, and then the engine consumes the[0-9]+digits. - The final match is
100(the$is not included in the match data).
4. Negative Lookbehind `(?
A negative lookbehind tells the engine: "Look to the LEFT. Ensure this pattern did NOT just happen."
Use Case: Match the word "cat" only if it is NOT part of the word "tomcat".
```regex
(?<!tom)cat
```
If the string is "I have a cat and a tomcat", this regex will only highlight the standalone "cat".
The Golden Rule of Lookarounds
The most important thing to remember is that Lookarounds do not consume characters.
If you write (?=foo)bar, the engine looks ahead for "foo". If it finds "foo", it stays in the exact same position, and then tries to match "bar". Since "foo" and "bar" cannot occupy the same space, this regex will always fail!
Always visualize the engine's "reading head" stopping, peeking through a telescope, and then retracting back to where it stood before making its next move.
Practice combining lookaheads and lookbehinds in our Interactive Regex Sandbox to truly master advanced pattern matching!





