DEV Community

Profiterole
Profiterole

Posted on

The JavaScript Regex Cheat Sheet: 10 Patterns That Cover 80 Percent of Your Use Cases

Regular expressions are one of those tools that look intimidating at first but become indispensable once you understand them. This guide covers the patterns you'll actually use in JavaScript projects — from form validation to parsing log files.

The Basics You Need to Know First

A regex in JavaScript looks like /pattern/flags. You can use it two ways:

// Method 1: Regex literal (preferred for static patterns)
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

// Method 2: RegExp constructor (use when pattern is dynamic)
const term = "error";
const logRegex = new RegExp(`\\b${term}\\b`, "gi");
Enter fullscreen mode Exit fullscreen mode

The most important flags:

  • g — global, find all matches (not just the first)
  • i — case-insensitive
  • m — multiline, ^ and $ match line start/end
  • s — dotAll, . matches newlines too

The 10 Patterns That Cover 80% of Use Cases

1. Email Validation

const isEmail = (str) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(str);

isEmail("user@example.com"); // true
isEmail("not-an-email");     // false
Enter fullscreen mode Exit fullscreen mode

Note: This catches obvious non-emails without being overly strict. RFC 5322 compliant regex is a 6-kilobyte nightmare — don't bother.

2. Phone Numbers (Flexible)

// Matches: (555) 123-4567, 555-123-4567, 5551234567, +1 555 123 4567
const phoneRegex = /^[+]?[(]?[0-9]{3}[)]?[-\s.]?[0-9]{3}[-\s.]?[0-9]{4,6}$/;
Enter fullscreen mode Exit fullscreen mode

3. Extract All URLs from Text

const extractUrls = (text) => {
  const urlRegex = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/g;
  return text.match(urlRegex) || [];
};

extractUrls("Visit https://example.com and https://dev.to for resources");
// ["https://example.com", "https://dev.to"]
Enter fullscreen mode Exit fullscreen mode

4. Strong Password Validation

// At least 8 chars, one uppercase, one lowercase, one digit, one special char
const isStrongPassword = (pwd) =>
  /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/.test(pwd);
Enter fullscreen mode Exit fullscreen mode

This uses lookaheads ((?=...)), which check for a condition without consuming characters. Each (?=.*[A-Z]) asserts "somewhere ahead there's an uppercase letter."

5. Normalize Whitespace

// Remove multiple spaces, collapse to single space
const normalizeSpaces = (str) => str.replace(/\s+/g, " ").trim();

normalizeSpaces("Hello    World   ");  // "Hello World"
Enter fullscreen mode Exit fullscreen mode

6. Slugify a String (for URLs)

const slugify = (str) =>
  str
    .toLowerCase()
    .replace(/[^\w\s-]/g, "")   // remove special chars
    .replace(/[\s_-]+/g, "-")   // spaces/underscores to hyphens
    .replace(/^-+|-+$/g, "");   // trim leading/trailing hyphens

slugify("Hello, World! This is a Test.");  // "hello-world-this-is-a-test"
Enter fullscreen mode Exit fullscreen mode

7. Extract Numbers from a String

const extractNumbers = (str) => str.match(/\d+(\.\d+)?/g)?.map(Number) || [];

extractNumbers("The price is $29.99 and tax is 3.5%");  // [29.99, 3.5]
Enter fullscreen mode Exit fullscreen mode

8. Validate Hex Colors

const isHexColor = (str) => /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(str);

isHexColor("#fff");      // true
isHexColor("#FF5733");   // true
isHexColor("red");       // false
Enter fullscreen mode Exit fullscreen mode

9. Find and Replace with Captured Groups

This is where regex gets really powerful. Parentheses () capture matched groups you can reference in replacements with $1, $2:

// Reformat date from MM/DD/YYYY to YYYY-MM-DD
const reformatDate = (date) => date.replace(/(\d{2})\/(\d{2})\/(\d{4})/, "$3-$1-$2");

reformatDate("03/21/2026");  // "2026-03-21"
Enter fullscreen mode Exit fullscreen mode
// Wrap all numbers in <strong> tags
const boldNumbers = (str) => str.replace(/(\d+)/g, "<strong>$1</strong>");

boldNumbers("You have 3 new messages and 12 pending tasks");
// "You have <strong>3</strong> new messages and <strong>12</strong> pending tasks"
Enter fullscreen mode Exit fullscreen mode

10. Parse Query Strings

const parseQueryString = (qs) => {
  const params = {};
  const regex = /[?&]([^=#]+)=([^&#]*)/g;
  let match;
  while ((match = regex.exec(qs)) !== null) {
    params[decodeURIComponent(match[1])] = decodeURIComponent(match[2]);
  }
  return params;
};

parseQueryString("?name=John&age=30&city=New%20York");
// { name: "John", age: "30", city: "New York" }
Enter fullscreen mode Exit fullscreen mode

Common Mistakes That Will Bite You

Forgetting the g Flag

// BUG: Only replaces the first occurrence
"aaa".replace(/a/, "b");   // "baa"

// Fix: Use the g flag
"aaa".replace(/a/g, "b");  // "bbb"
Enter fullscreen mode Exit fullscreen mode

Escaping Special Characters in User Input

If you're building a regex from user input, always escape it first:

const escapeRegex = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");

// Safe search highlight
const highlightTerm = (text, term) => {
  const escaped = escapeRegex(term);
  return text.replace(new RegExp(`(${escaped})`, "gi"), "<mark>$1</mark>");
};
Enter fullscreen mode Exit fullscreen mode

Without escapeRegex, a user searching for (test) would throw a regex syntax error.

The Catastrophic Backtracking Trap

This regex looks fine but will hang your browser on certain inputs:

// DANGEROUS — exponential backtracking
/^(a+)+$/.test("aaaaaaaaaaaaaaaaaaaaaaaaaaab");
Enter fullscreen mode Exit fullscreen mode

The fix: avoid nested quantifiers on overlapping patterns. Test your regex with adversarial inputs before shipping.

Debugging Complex Patterns

When a regex isn't working, break it into smaller pieces and test each part in isolation. I use the free developer tools at Profiterole for quick testing — being able to visually see which groups match what saves a lot of trial and error. If you're also working with TypeScript and extracting structured data, their JSON-to-TypeScript converter pairs well once you've got your regex outputting the right shape.

Quick Reference Cheat Sheet

Symbol Meaning
. Any character except newline
\d Digit [0-9]
\w Word char [a-zA-Z0-9_]
\s Whitespace
^ Start of string/line
$ End of string/line
* 0 or more
+ 1 or more
? 0 or 1
{n,m} Between n and m times
(...) Capture group
(?:...) Non-capturing group
(?=...) Positive lookahead
(?!...) Negative lookahead
[abc] Character class
[^abc] Negated character class

Putting It All Together

Here's a real-world function that sanitizes and validates a user comment:

function processComment(raw) {
  // Remove script tags
  const noScript = raw.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, "");

  // Normalize whitespace
  const normalized = noScript.replace(/\s+/g, " ").trim();

  // Check for spam patterns
  const spamPattern = /\b(buy now|click here|free money|earn \$\d+)\b/i;

  if (normalized.length < 10) return { valid: false, reason: "Too short" };
  if (spamPattern.test(normalized)) return { valid: false, reason: "Spam detected" };

  return { valid: true, content: normalized };
}
Enter fullscreen mode Exit fullscreen mode

Regular expressions reward the time you put in. The 10 patterns above cover the vast majority of what you'll encounter day-to-day — bookmark this page and the next time you're tempted to reach for a string library, try a quick regex first.


What regex pattern do you find yourself rewriting from scratch most often? Share it in the comments.

Top comments (0)