/^/

Lesson 5 of 28

Anchors

Matching positions instead of characters: ^ and $ for start/end of string, \b and \B for word boundaries, and how the m flag changes things.

6 min read

Everything so far — literals, character classes — matches actual characters. Anchors are different: they match a position in the string without consuming any characters themselves. They let you say “only at the start,” “only at the end,” or “only where a word begins or ends.”

^ and $ — start and end of string

^ anchors a match to the beginning of the string; $ anchors it to the end. Used together, they force the entire string to match the pattern, not just some substring of it.

/^Hello/.test("Hello world"); // true — starts with "Hello"
/^Hello/.test("Say Hello");   // false — "Hello" isn't at the start
/World$/.test("Hello World"); // true — ends with "World"
Hello world
1 match

Multiline mode: the m flag

By default, ^ and $ only care about the very start and very end of the whole string — even if that string spans multiple lines. Add the m flag and they instead anchor to the start and end of every line:

const text = "Hello world\nSay Hello\nHello there";
/^Hello/.test(text);   // true — matches at the very start of the string
/^Hello/m.test(text);  // still true, but now for a different reason
Hello world Say Hello Hello there
2 matches

With the m flag and the g flag (used together in the demo above to find every match, not just the first), ^Hello matches at the start of line 1 and the start of line 3 — but not line 2, because "Say Hello" doesn’t begin with Hello. Without m, only the very first line’s Hello would ever be reachable by ^, no matter how many lines follow.

Mode ^ matches $ matches
Default (no m) Start of the whole string End of the whole string
With m flag Start of every line End of every line

Tip

Don’t confuse multiline mode (m) with dot-matches-newline mode (often called s or “dotall” in other engines) — they control different things. m changes what ^/$ mean; s changes whether . can match a newline character.

\b — word boundaries

\b matches the invisible position between a “word” character (\w: letters, digits, underscore) and a “non-word” character (anything else, including the start/end of the string). It’s what makes “whole word” matching possible without anchoring to the entire string.

/cat/.test("concatenate");    // true — "cat" is just a substring
/\bcat\b/.test("concatenate"); // false — "cat" isn't a whole word here
/\bcat\b/.test("a cat sat");  // true — "cat" stands alone
cat cats concatenate the cat
2 matches

The demo matches the two standalone occurrences of cat, but correctly skips cats (because there’s no boundary between t and s — both are word characters) and skips the cat hiding inside concatenate.

\B — NOT a word boundary

\B is the negation of \b: it matches a position that is not a word boundary — meaning it’s either fully inside a word (word character on both sides) or fully inside a run of non-word characters.

concatenate cat scatter
2 matches

Here \Bcat\B matches inside concatenate and inside scatter — both have a word character immediately before and after the cat substring — but skips the standalone cat, since spaces surround it on both sides (making those boundaries \b, not \B).

Try it yourself

Using the last demo, change the pattern from \Bcat\B to just cat (no boundaries at all) and compare how many matches you get across the same text.

What should happen

Plain cat matches all three occurrences — inside concatenate, the standalone word, and inside scatter — because it doesn’t care about what surrounds the match. Adding \B on both sides filters that down to only the two “embedded” occurrences, which is exactly the kind of precision anchors are for.

What’s next

Anchors control where a match can start or end, but so far every character in our patterns has appeared exactly once. The next lesson covers quantifiers*, +, ?, and {n,m} — which control how many times a piece of a pattern can repeat.

Quick check

What does ^ match when the m (multiline) flag is NOT set?

What's the difference between \b and \B?