Anchors ^ $ \b
Anchors match positions, not characters. ^ = start of string / line, \$ = end of string / line, \b = word boundary, \B = not-a-word-boundary. The shape of every disciplined regex.
All the anchors with examples
EXAMPLE
// 1) ^ — start of string
/^Hello/.test('Hello world') // true
/^Hello/.test('say Hello') // false
// 2) $ — end of string
/world$/.test('Hello world') // true
/world$/.test('world peace') // false
// 3) Combine — exact match
const isInteger = /^-?\d+$/;
isInteger.test('42') // true
isInteger.test('42abc') // false
// 4) Multiline flag — ^ and $ match every LINE, not just start/end of string
const lines = 'line one\nline two\nERROR\nline four';
lines.match(/^ERROR$/m)?.[0] // 'ERROR'
lines.match(/^line.*$/gm) // every line starting with 'line'
// 5) \b — word boundary (between \w and \W or start/end)
/\bcat\b/.test('the cat sat') // true
/\bcat\b/.test('caterpillar') // false
/\bcat\b/.test('a-cat-here') // true (- is not a word char)
// Useful pattern — match a WHOLE word
/\bclass\b/g // matches 'class' but not 'classroom'
// 6) \B — NOT a word boundary
/\Bcat\B/.test('caterpillar') // false (start of cat is a boundary)
/\Bcat\B/.test('scatter') // true (cat is in the middle)
// 7) \A and \z — start/end of STRING in PCRE / Python / Ruby (NOT JS)
# Python
# import re
# re.search(r'\Astart', 'start of string') # like ^ but ignores multiline
# re.search(r'end\z', 'end of string') # like $ but ignores multiline
// 8) (?=) — lookahead (zero-width assertion, NOT an anchor but acts like one)
/foo(?=bar)/.test('foobar') // true — 'foo' followed by 'bar'
/foo(?!bar)/.test('foobaz') // true — 'foo' NOT followed by 'bar'
/(?<=USD)\d+/.exec('USD42')?.[0] // '42' (lookbehind, modern JS)
// 9) Real recipes
// 9a) Trim whitespace
' hello world '.replace(/^\s+|\s+$/g, '')
// 9b) Match leading hash tag
'/users/42/posts'.match(/^\/users\/(\d+)/)?.[1]
// 9c) Match line not starting with #
config.split('\n').filter(l => /^[^#].+/.test(l))
// 9d) Standalone TODO comments (whole word)
'fix this todo'.match(/\bTODO\b/gi)
// 9e) Email-like (intentionally rough — you should NOT validate email with regex; use a library)
const rough = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
// 10) Pitfalls
// • Forgetting ^ + $ when validating → '42abc' passes a number check
// • Using \b in code that allows -, _, or unicode — \b is ASCII word chars only
// • Multiline mode changes ^/$ meaning — be intentional with the m flag
// • Anchors don't consume characters — they're zero-width
// 11) Regex flags cheat sheet (JS)
// g — global (find all)
// i — case-insensitive
// m — multiline (^/$ per line)
// s — dotall (. matches \n)
// u — unicode
// y — sticky (matches from lastIndex only)
// v — modern unicode (set ops + named props)
// 12) Tools
// • regex101.com — visualise + benchmark
// • regexr.com — quick reference
// • RE2 (in ripgrep, Go) — linear time, no catastrophic backtracking
Why it matters
Always wrap validation regex in ^...\$. Without them, /[0-9]+/ matches “42” inside “Order 42abc shipped” — the most-shipped silent bug class in regex code.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
^foo // start of string (or line with m flag) bar$ // end of string \bword\b // word boundary \Bword // NOT at a word boundaryTry it Yourself »
Exercise
Anchor for end of string.
/foo
/
One character.
Discussion
Loading…