JavaScript RegExp $ Quantifier

Beginner
⏱️ 9 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
End anchor

What You’ll Learn

The $ quantifier is an end anchor. It matches a position—not a character—at the end of the input string. Combine it with literal text or groups to require a suffix: file extensions, domain endings, punctuation, or keywords that must appear last.

01

$ anchor

End of string

02

Zero-width

No characters

03

$ + m

Each line end

04

Suffix

.pdf, ing

05

Not replace

Pattern vs $1

06

Pair ^

Full-line match

Introduction

Many validation tasks care about where text appears, not just what it contains. Does a filename end in .pdf? Does a sentence end with a question mark? Does a log line finish with OK? The $ anchor answers those questions by insisting the match reaches the end of the string.

Without $, the pattern /world/ matches "hello world" anywhere the letters appear. Adding $ turns it into /world$/, which matches only when world is the final characters—a much stricter and often more useful rule.

Understanding the $ End Anchor

Place $ at the end of a pattern (or before a trailing flag like /i). It asserts that the current match position is at the end of the input. With the m multiline flag, it also matches immediately before each newline, so each line can have its own “end.”

JavaScript
const ok = "hello world";
const no = "world hello";

/world$/.test(ok);  // true  — ends with "world"
/world$/.test(no);  // false — "world" is not at the end

/end$/m.test("line one end\nline two end"); // true — both lines end with "end"

$ is zero-width: it checks a boundary without consuming characters. That is why /world$/ on "hello world" matches the substring "world" at the string tail.

💡
Beginner Tip

Do not confuse $ in a pattern with $1 in a replacement string. In str.replace(/(\w+)$/, "[$1]"), the first $ is an end anchor; the $1 in the replacement refers to the captured word.

How to Use the $ Anchor

Append text or groups before $ to require a suffix, or pair ^ and $ to match an entire line or string:

JavaScript
/\.pdf$/i.test("report.PDF");     // true — extension at end
/\d+$/.test("item42");             // true — trailing digits
/^.+$/m.test("a\nb\nc");           // true — each line non-empty

"photo.jpg".replace(/\.(jpg|png)$/i, ".webp"); // "photo.webp"

Use test() for yes/no checks, match() to extract the suffix, and replace() to rewrite endings. Add m when working with multi-line strings.

📝 Syntax

JavaScript
/suffix$/              // ends with literal "suffix"
/\.(jpg|png)$/i        // image extension at end
/\d+$/                 // one or more digits at end
/pattern$/m            // end of each line (with m)
/^start.+end$/         // whole string from start to end
new RegExp("end$", "m") // constructor form

Common patterns

  • /\.(pdf|docx?)$/i — document file extensions.
  • /[!?.]$/ — sentence ends with punctuation.
  • /^\s*$/m — find blank lines (with m).
  • /ing$/i — words ending in ing.
  • /^.+$/gm — capture every non-empty line.

⚡ Quick Reference

GoalPattern / API
Ends with text/text$/
Ends with extension/\.ext$/i
Ends with digits/\d+$/
End of each line/pattern$/m
Full string match/^pattern$/
Capture suffix group/(.+)$/.exec(str)[1]

📋 $ in Patterns vs Replacements

Same symbol, different jobs depending on where it appears.

Pattern
/world$/

End anchor — must finish with world

Replacement
"[$1]"

$1 inserts capture group 1

No $
/world/

Matches anywhere in string

With $
/world$/

Only when world is last

Examples Gallery

Open DevTools Console (F12) or use Try-it links. Examples cover basic suffix matching, multiline line ends, file extensions, trailing digits, and full-line validation with ^ and $.

📚 Getting Started

Require text at the end of a string.

Example 1 — Match a Suffix with $

Check whether a string ends with world.

JavaScript
const phrases = ["hello world", "world peace", "say world"];

phrases.forEach((s) => {
  console.log(s, /world$/.test(s));
});
// "hello world" true
// "world peace" false
// "say world"   true
Try It Yourself

How It Works

$ forces the engine to reach the string tail. "world peace" contains world but not at the end, so the test fails.

📈 Practical Patterns

Line endings, extensions, and validation.

Example 2 — End of Each Line with $ and m

Find lines that end with end in multi-line text.

JavaScript
const text = "line one end\nline two end\nno match";

console.log(/end$/.test(text));    // false — whole string ends with "match"
console.log(/end$/m.test(text));   // true — lines 1 and 2 end with "end"

console.log(text.match(/end$/gm)); // ["end", "end"]
Try It Yourself

How It Works

Without m, $ only checks the final character of the entire string. With m, each newline creates an additional end position. Add g to collect every matching line ending.

Example 3 — Validate File Extensions

Accept only filenames ending in .jpg or .png.

JavaScript
const isImage = /\.(jpe?g|png)$/i;

console.log(isImage.test("photo.jpg"));      // true
console.log(isImage.test("photo.JPEG"));     // true
console.log(isImage.test("photo.jpg.bak")); // false
Try It Yourself

How It Works

Escaping the dot (\.) matches a literal period. The alternation group lists allowed extensions, and $ ensures nothing follows them.

Example 4 — Trailing Digits at the End

Extract product codes that end with one or more digits.

JavaScript
const items = ["widget7", "widget42", "widget"];

items.forEach((name) => {
  const m = name.match(/(\d+)$/);
  console.log(name, m ? m[1] : "no digits");
});
// widget7  "7"
// widget42 "42"
// widget   "no digits"
Try It Yourself

How It Works

\d+ greedily matches digits; $ anchors them to the tail. The captured group returns just the number portion.

Example 5 — Full-Line Match with ^ and $

Ensure an entire string matches a pattern from start to finish.

JavaScript
const hexColor = /^#[0-9a-f]{6}$/i;

console.log(hexColor.test("#ff00aa"));     // true
console.log(hexColor.test("#ff00"));       // false — too short
console.log(hexColor.test("color #ff00aa")); // false — extra text
Try It Yourself

How It Works

^ pins the match to the start; $ pins it to the end. Together they reject partial or embedded matches—ideal for strict format validation.

🚀 Common Use Cases

  • File type checks — allow uploads only when the name ends with a safe extension.
  • URL/path suffixes — detect trailing slashes or specific route endings.
  • Input validation — require entire field to match a format with ^…$.
  • Log parsing — find lines ending in ERROR, OK, or a status code.
  • Natural language — detect sentences ending in ?, !, or .
  • Data cleanup — strip or rewrite suffixes with replace(/suffix$/, …).

Important Considerations

  • Multiline text — add m when $ should apply per line, not only at string end.
  • Trailing whitespace — spaces before the end prevent $ from matching where you expect; trim or use \s*$ if needed.
  • Not a character$ is an assertion; it does not match the last letter itself.
  • Replacement confusion$1 in replace strings is a backreference, not an anchor.
  • Windows line endings\r\n may leave \r before $ matches; normalize line endings when parsing.
  • Partial vs full match — without ^, /pattern$/ still allows extra text at the start.

🧠 How the $ Anchor Works

1

Match preceding part

The engine matches literal text, classes, or groups before $.

Pattern
2

Reach end position

$ succeeds only if the cursor is at string end—or before \n when m is set.

Anchor
3

Report match

The matched substring is everything from the start of the attempt through the last consumed character.

Result
4

Collect with g

Use gm to find every line that ends with your suffix pattern.

📝 Notes

  • $ pairs naturally with ^ for whole-string or whole-line validation.
  • See the m modifier for per-line $ behavior.
  • Previous topic: m multiline flag.
  • Next topic: ?! negative lookahead.
  • \b word boundaries differ from $; see \b.
  • In replacement strings, use $$ for a literal dollar sign.

Browser & Runtime Support

The $ end anchor is part of core JavaScript regular expression syntax.

Baseline · ES3+

RegExp $ anchor

Supported in every browser and Node.js version. Combine with m for line-by-line end matching.

99% Universal syntax
Google Chrome Supported · Desktop & Mobile
Full support
Mozilla Firefox Supported · Desktop & Mobile
Full support
Apple Safari Supported · macOS & iOS
Full support
Microsoft Edge Supported · Chromium
Full support
Internet Explorer No native support · Use a polyfill
Polyfill
Opera Supported · Modern versions
Full support
Samsung Internet Supported · Android
Full support
Bun Supported · JavaScript runtime
Supported
Deno Supported · JavaScript runtime
Supported
Node.js Supported · Server runtime
Supported
Android WebView Supported · Modern WebView
Full support
$ Excellent

Bottom line: Safe everywhere. Use $ when a pattern must finish at the end of a string or line.

Conclusion

The $ quantifier is the end anchor: it ensures your pattern finishes where you expect—at the tail of a string, a filename, or (with m) each line of multi-line text. It is zero-width, precise, and essential for suffix checks and strict validation.

Remember the difference between $ in patterns and $1 in replacements, add m for multi-line input, and pair ^ with $ when the entire value must match. Next, explore ?! negative lookahead.

💡 Best Practices

✅ Do

  • Use $ when suffix position matters (extensions, endings)
  • Add m for multi-line strings that need per-line ends
  • Combine ^ and $ for strict full-value validation
  • Escape literal dots in extensions: \.pdf$
  • Test with real input including trailing spaces and \r\n

❌ Don’t

  • Confuse pattern $ with replacement $1
  • Forget m when matching line endings in logs or configs
  • Assume $ consumes the last character
  • Use /pattern$/ alone when the whole string must match
  • Mix up $ end anchor with \b word boundary

Key Takeaways

Knowledge Unlocked

Five things to remember about the RegExp $ anchor

Match suffixes and end-of-string patterns with confidence.

5
Core concepts
📈 02

Zero-width

No chars eaten.

Concept
📄 03

$ + m

Line ends.

Multiline
🔒 04

^ $

Full match.

Validate
🚫 05

Not $1

Replace only.

Pitfall

❓ Frequently Asked Questions

In a pattern, $ is a zero-width end anchor. It matches a position at the end of the input string, or—when the m (multiline) flag is set—immediately before each newline character. It does not consume any characters.
No. In a pattern, $ asserts end of string or line. In a replacement string passed to replace() or replaceAll(), $1, $2, etc. refer to capture groups, and $$ inserts a literal dollar sign. The meaning depends on context.
Use $ with m when your text contains newlines and you want to match the end of each line—not only the very last character of the entire string. Example: /end$/m matches end at the close of every line.
By default, $ matches the end of the string. With m, it also matches the position before an internal newline. A final trailing \n may still affect whether text before it is considered at line end—test with your actual input.
$ matches end of string or line (with m). \b matches a word boundary between word and non-word characters. /ing\b/ finds ing as a word suffix; /ing$/ requires ing to be at the string or line end.
The $ anchor is core JavaScript regex syntax since ES3. It works in every browser and Node.js version. Multiline behavior with m is equally universal.
Did you know?

JavaScript borrowed the $ end anchor from Perl-style regular expressions decades ago. The same symbol does double duty in replace() replacement strings—which is why reading regex documentation carefully (pattern vs replacement context) saves hours of debugging.

Continue to ?! negative lookahead

Learn how lookahead assertions match patterns not followed by specific text.

?! quantifier tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

6 people found this page helpful