JavaScript Notes
Build 10 practical JavaScript regex projects with complete code examples. Email extractor, phone formatter, card masker & more regex mini-projects.
Introduction
Regular expressions (regex) are one of the most powerful tools in a JavaScript developer's toolkit — but they can feel abstract until you apply them to real problems. The best way to master regex is by building actual projects that solve everyday text-processing challenges.
In this tutorial, we'll build 10 practical mini-projects using JavaScript regex. Each project tackles a real-world scenario — from extracting emails to masking credit card numbers, converting date formats, and more. By the end, you'll have a solid portfolio of regex utilities you can reuse in your own applications.
What you'll learn:
- How to use
match(),replace(),test(),exec(), andmatchAll()effectively - Capturing groups, lookaheads, and backreferences in practice
- Real-world patterns for validation, extraction, and transformation
- How to combine multiple regex operations for complex tasks
Prerequisites: Basic knowledge of JavaScript and fundamental regex syntax (character classes, quantifiers, anchors).
Project 2: Phone Number Formatter
Goal: Take a 10-digit phone number in any format and convert it to the standard (xxx) xxx-xxxx format. This is commonly needed in forms and CRM systems.
Phone Number Formatter: ───────────────────────────────────────────── "9876543210" → (987) 654-3210 "987-654-3210" → (987) 654-3210 "987.654.3210" → (987) 654-3210 "(987) 654 3210" → (987) 654-3210 "98 76 54 32 10" → (987) 654-3210 "12345" → Error: Expected 10 digits, got 5
How it works:
\Dmatches any non-digit character — we replace all of them with empty string(\d{3})(\d{3})(\d{4})creates three capture groups for the area code, prefix, and line number$1,$2,$3reference the captured groups in the replacement string
Project 3: Credit Card Masker
Goal: Mask a credit card number to show only the last 4 digits, replacing the rest with asterisks. Essential for displaying payment info securely in UIs and logs.
Credit Card Masker: ────────────────────────────────────────────────── Input: 4111 1111 1111 1234 Output: **** **** **** 1234 Input: 5500-0000-0000-5678 Output: **** **** **** 5678 Input: 378282246310005 Output: **** **** ***0 005 Input: 1234 Output: Error: Invalid card number Input: 6011000000000004 Output: **** **** **** 0004
How it works:
\d(?=\d{4})uses a positive lookahead — it matches any digit that has at least 4 more digits after it- This ensures only the last 4 digits remain unmasked
- The formatting step uses
(.{4})to group characters into blocks of 4
Project 4: Markdown to HTML Converter
Goal: Convert basic Markdown syntax (bold, italic, headers, links) to HTML. This is a simplified version of what tools like marked.js do internally.
Input Markdown: # Hello World ## Introduction This is **bold** and this is *italic*. Here is a [link](https://wohotech.in) and some ~~deleted~~ text. Use `console.log()` for debugging. ### Summary Learning regex is __important__ for _every_ developer. Converted HTML: <p><h1>Hello World</h1><br><h2>Introduction</h2><br>This is <strong>bold</strong> and this is <em>italic</em>.<br>Here is a <a href="https://wohotech.in">link</a> and some <del>deleted</del> text.<br>Use <code>console.log()</code> for debugging.<br><h3>Summary</h3><br>Learning regex is <strong>important</strong> for <em>every</em> developer.</p>
How it works:
- Order matters — we process
###before##before#to avoid partial matches - Bold (
**) is processed before italic (*) sobolddoesn't get caught by italic rules .+?uses lazy (non-greedy) matching to capture the shortest match between delimiters^with themflag matches the start of each line for headers
Project 5: Word Counter
Goal: Build a text analysis tool that counts words, sentences, paragraphs, and unique words. Useful for content editors, SEO tools, and writing applications.
Text Analysis Results:
───────────────────────────────────
Words: 54
Sentences: 9
Paragraphs: 3
Unique words: 41
Avg words/sent: 6
Top 5 words:
"is" → 3 times
"regex" → 3 times
"projects" → 3 times
"javascript" → 2 times
"help" → 2 timesHow it works:
\b[a-zA-Z']+\bmatches whole words including apostrophes (for contractions like "don't")[^.!?]*[.!?]+matches everything up to sentence-ending punctuation\n\s*\nmatches blank lines (with optional whitespace) between paragraphs- We use a
Setto efficiently find unique words
Project 6: Search & Highlight
Goal: Find all occurrences of a search term in text and wrap them with highlight markers. This simulates the "find" feature in text editors and browsers.
Search term: "javascript" Matches found: 4 Positions: [0, 36, 100, 133] Highlighted text: 【JavaScript】 is amazing. Learning 【JavaScript】 helps you build web apps. Many developers love 【JavaScript】 for its flexibility. 【javascript】 is everywhere. ────────────────────────────────────────────────── Case-sensitive search: "JavaScript" Matches found: 3 Highlighted text: 【JavaScript】 is amazing. Learning 【JavaScript】 helps you build web apps. Many developers love 【JavaScript】 for its flexibility. javascript is everywhere.
How it works:
- We escape special regex characters (
.*+?^${}()|[]\\) in user input to prevent regex injection new RegExp()lets us build patterns dynamically from variables(${escaped})creates a capture group so we can reference it with$1in the replacementmatchAll()gives us positions (index) of each match
Project 7: IP Address Validator
Goal: Validate IPv4 addresses and classify them (valid, invalid, private, loopback). Network tools and firewalls use this kind of validation constantly.
IP Address Validator: ─────────────────────────────────────────────────────── 192.168.1.1 ✓ Valid — Private (Class C) 10.0.0.255 ✓ Valid — Private (Class A) 172.16.0.1 ✓ Valid — Private (Class B) 127.0.0.1 ✓ Valid — Loopback 8.8.8.8 ✓ Valid — Public 256.1.2.3 ✗ Invalid — Octet 256 exceeds 255 192.168.1 ✗ Invalid — Invalid format 01.02.03.04 ✗ Invalid — Leading zeros not allowed 255.255.255.255 ✓ Valid — Broadcast 0.0.0.0 ✓ Valid — Invalid (network)
How it works:
^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$captures each octet in a group- We use
^and$anchors to ensure the entire string matches (no partial matches) - After regex validation, we numerically check each octet is ≤ 255
\b0\ddetects leading zeros like "01" or "007"- Classification checks well-known private IP ranges (RFC 1918)
Project 8: Date Format Converter
Goal: Convert dates between DD/MM/YYYY and YYYY-MM-DD formats, with validation. This is essential when working with international date formats or database timestamps.
Date Format Converter:
───────────────────────────────────────────────────────
"25/12/2026" → "2026-12-25" (ISO)
"2026-06-12" → "12/06/2026" (DD/MM/YYYY)
"06-15-2026" → "15 Jun 2026" (long)
"31/02/2026" → "2026-02-31" (ISO)
"invalid-date" → Error: Unrecognized date format
All formats for '25/12/2026':
ISO → 2026-12-25
DD/MM/YYYY → 25/12/2026
MM-DD-YYYY → 12-25-2026
YYYY/MM/DD → 2026/12/25
long → 25 Dec 2026How it works:
- Three different regex patterns detect the input format automatically
- Destructuring assignment
[, day, month, year] = matchextracts capture groups - We validate month (1-12), day (1-31), and year (1900-2100) numerically
- The function returns all possible output formats so the caller can choose
Project 9: HTML Tag Stripper
Goal: Remove HTML tags from a string while preserving text content. Also handles decoding common HTML entities. Useful for sanitizing user input and extracting readable text from HTML.
Original HTML (truncated):
<html>
<head><style>body { color: red; }</style></head>
<body>
<h1>Welcome to WoHoTech</h...
Stripped text:
Welcome to WoHoTech
Learn JavaScript & regex easily.
HTML entities: <tag> and "quotes"
Item 1
Item 2 — important
© 2026 WoHoTech. All rights reserved.How it works:
<script\b[^>]*>[\s\S]*?<\/script>removes script tags AND their content (lazy*?prevents greedy matching)<[^>]+>matches any HTML tag —[^>]+matches everything except>- We convert block elements to
\nbefore stripping to preserve document structure - Entity replacement uses a lookup object with regex to find and replace all entities
Project 10: Censorship Filter
Goal: Replace bad words or sensitive content with asterisks while preserving surrounding text. This is used in chat applications, forums, and content moderation systems.
Censorship Filter: Bad words: spam, hack, crack, exploit, malware ──────────────────────────────────────────────────────────── Original: Learn to hack ethically and find exploits in systems. Censored: Learn to h*** ethically and find e******* in systems. Words censored: 2 (hack, exploits) Original: This is spam content about malware and cracking passwords. Censored: This is s*** content about m****** and c******* passwords. Words censored: 3 (spam, malware, cracking) Original: Normal text about JavaScript programming. Censored: Normal text about JavaScript programming. Words censored: 0 (none) Original: Don't SPAM people or spread MALWARE online! Censored: Don't S*** people or spread M****** online! Words censored: 2 (spam, malware)
How it works:
\\b(word boundaries) ensures we match whole words only — "hacker" won't be partially censoredescapedWords.join('|')creates an alternation pattern likespam|hack|crack|exploit|malware- The replacement function uses
match.lengthto generate the correct number of asterisks preserveFirstLetteroption keeps the first character visible for readability- Case-insensitive flag ensures "SPAM" and "spam" are both caught
🎯 Key Takeaways
After building these 10 regex projects, here are the essential lessons:
- Start with
.replace()and.match()— These two methods handle 80% of regex tasks in JavaScript.
- Always use appropriate flags —
gfor global (all matches),ifor case-insensitive,mfor multiline.
- Escape user input — When building regex from variables, always escape special characters with
str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&').
- Use non-greedy matching —
.*?and.+?prevent regex from matching more than intended, especially in HTML/markdown parsing.
- Lookaheads are powerful —
(?=...)lets you match based on what follows without consuming characters (like in credit card masking).
- Capture groups + backreferences —
()captures text that$1,$2can reference in replacements. Essential for reformatting.
- Word boundaries
\bprevent partial matches — Without them, "cat" would match inside "category".
- Validate after matching — Regex can check format, but numeric validation (like IP octets ≤ 255) needs JavaScript logic.
- Order matters in alternation — Process longer/more specific patterns first (like
###before#in markdown).
- Test edge cases — Empty strings, special characters, extremely long input, and Unicode text can all break naive patterns.
📝 FAQ
Q1: Can I use these regex projects in production applications?
Yes! These patterns are production-ready for common use cases. However, for critical validation (like email — RFC 5322 is extremely complex), consider using well-tested libraries alongside regex. The patterns here cover 95% of real-world scenarios and are excellent starting points.
Q2: Why does the email regex not catch all valid email addresses?
The email regex we used is intentionally simplified. RFC 5322 compliant email validation requires an extremely complex pattern (thousands of characters). Our pattern handles the vast majority of real-world emails. For 100% compliance, use a library like validator.js or validate by sending a confirmation email.
Q3: How do I handle Unicode characters in regex projects?
Use the u flag for Unicode support: /\p{L}+/gu matches any Unicode letter. For emoji matching, use /\p{Emoji}/gu. Without the u flag, patterns like . won't properly match characters outside the Basic Multilingual Plane (like emoji or some Asian characters).
Q4: What's the performance impact of complex regex on large texts?
Regex performance depends on pattern complexity. Avoid catastrophic backtracking by not nesting quantifiers (like (a+)+). For very large texts (>1MB), consider:
- Processing text in chunks
- Using simpler patterns with multiple passes
- Pre-filtering with
indexOf()before applying regex - Using
matchAll()instead of repeatedexec()calls
Q5: How can I debug regex patterns when they don't work as expected?
Use these approaches: (1) Test on regex101.com with your exact input — it explains each step. (2) Use console.log(regex.exec(text)) to see match details including groups. (3) Build patterns incrementally — start with the simplest version and add complexity. (4) Use named capture groups (?<name>...) for clarity in complex patterns.
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for JavaScript Regex Projects — 10 Practical Mini-Projects with Code 2026.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this JavaScript Master Course topic.
Search Terms
javascript-complete-guide, javascript master course, javascript, complete, guide, regex, projects, javascript regex projects — 10 practical mini-projects with code 2026
Related JavaScript Master Course Topics