Lab: lookarounds
Practice positive and negative lookahead and lookbehind on realistic strings — from config parsing to content filtering.
- Apply positive and negative lookaheads to extract or filter matches by following context
- Apply lookbehind to extract values from labelled contexts
- Combine multiple lookarounds for compound conditions
Optional lab. These exercises practise all four lookaround types on tasks that come up in real parsing work. Run each exercise, compare to the hints, and try your own variations.
Warm up — see lookarounds in action
Notice how the match changes when the lookahead is included vs excluded:
Checkpoint 1 — extract USD amounts
Extract all numbers (integers or decimals) that are followed by USD from a
prices string.
Write getUsdAmounts(text) returning an array of number strings (as returned by match) that are followed by " USD" or " usd" (case-insensitive).
getUsdAmounts('10 USD and 5 EUR') → ['10']getUsdAmounts('price 9.99 USD tax 0.75 USD') → ['9.99', '0.75']Checkpoint 2 — filter out config values for excluded keys
Given a config string key=value key2=value2 …, return only the values for
keys that are NOT password or secret.
Write getSafeValues(config) returning an array of values (the part after =) for all keys in "key=value" pairs, EXCLUDING keys named "password" or "secret" (case-insensitive).
getSafeValues('host=localhost password=abc123') → ['localhost']If the lookbehind approach in the starter code feels complex, an alternative is
to use a capturing group and filter: match all key=value pairs, then discard
the ones with sensitive keys. Both approaches work — lookarounds produce a
cleaner match object; filtering is more readable.
Checkpoint 3 — match words before a colon
Extract all "key" words that appear immediately before a colon and space in a
key: value style string.
Write getKeys(text) returning an array of all words that are immediately followed by ": " (colon then space) in the input text.
getKeys('name: Alice age: 30') → ['name', 'age']Checkpoint 4 — password validation
Return true if a password has at least 8 characters, at least one uppercase
letter, at least one digit, and at least one of !@#$%.
Write isStrongPassword(pw) returning true if pw is at least 8 characters long, contains at least one uppercase letter [A-Z], at least one digit, and at least one special character from [!@#$%]. Use stacked lookaheads.
isStrongPassword('Passw0rd!') → trueisStrongPassword('passw0rd!') → false — no uppercaseDone?
All four green? You can now write patterns with precise context conditions that would be impossible — or painfully verbose — without lookarounds.
You have completed the full regex track. The tools you have learned:
- Literals, metacharacters, character classes, quantifiers, anchors
- Groups and alternation, the dot wildcard, flags
- Common real-world patterns
- Capturing, named, and non-capturing groups
- Backreferences in patterns and replacements
- Positive and negative lookahead and lookbehind
For further practice, use regex101.com with real data from your own projects. The best way to get sharper is to reach for regex when you would otherwise write a loop, and see how concisely you can express the pattern.
Combining lookarounds
Stack multiple lookaheads and lookbehinds at the same position to express precise, multi-condition matching — including the classic password validation pattern.
Catastrophic backtracking
Understand how NFA regex engines backtrack, why certain patterns cause exponential slowdowns, and how to rewrite them safely.