Regular Expressions Mastery
JS-এর ভেতরে লুকানো ছোট একটি ভাষা
1. Two Ways to Write a Regex
create.js
// Literal — preferred when the pattern is fixed
const r1 = /hello/i;
// Constructor — when the pattern is built dynamically
const name = "world";
const r2 = new RegExp(`hello ${name}`, "i");
console.log(r1.test("Hello World"));
console.log(r2.test("hello WORLD"));
2. Flags Cheat Sheet
| Flag | Meaning |
|---|---|
g | Global — find all matches, not just first |
i | Case-insensitive |
m | Multi-line — ^ and $ match per line |
s | "dotall" — . matches newline |
u | Unicode — required for \u{...} and full Unicode classes |
y | Sticky — anchored at lastIndex |
3. Atoms & Classes
| Token | Matches |
|---|---|
. | Any char except newline (or any with s flag) |
\d \D | Digit / non-digit |
\w \W | Word char / non-word |
\s \S | Whitespace / non-whitespace |
[abc] / [^abc] | Set / negated set |
[a-z] | Range |
^ $ | Start / end of string (or line with m) |
\b \B | Word boundary / non-boundary |
4. Quantifiers
a* // 0 or more
a+ // 1 or more
a? // 0 or 1
a{3} // exactly 3
a{2,5} // 2 to 5
a{2,} // 2 or more
a*? // lazy — fewest possible
.+?
5. Groups & Backreferences
groups.js
// Capturing
const m1 = "2026-05-09".match(/(\d{4})-(\d{2})-(\d{2})/);
console.log(m1[1], m1[2], m1[3]); // 2026 05 09
// Named
const m2 = "2026-05-09".match(/(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})/);
console.log(m2.groups);
// Non-capturing — group without remembering
console.log(/(?:abc)+/.test("abcabc"));
// Backreference — repeated word
console.log(/\b(\w+)\s+\1\b/.test("the the cat")); // true
6. Lookahead & Lookbehind
(?=...) positive lookahead foo(?=bar) "foo" only if followed by "bar"
(?!...) negative lookahead
(?<=...) positive lookbehind
(?<!...) negative lookbehind
look.js
// Match price digits, not the currency symbol
console.log("৳1500".match(/(?<=৳)\d+/)[0]);
// Strong-password assertion
const strong = /^(?=.*\d)(?=.*[!@#$%^&*])(?=.{8,}).*$/;
console.log(strong.test("abcdef1!"));
console.log(strong.test("abc"));
7. Methods That Use Regex
/abc/.test(s) // boolean
s.match(/abc/) // first match (or all if g)
s.matchAll(/abc/g) // iterator of full match objects
s.replace(/abc/, "X") // first
s.replaceAll(/abc/g, "X") // all (g flag required for str → regex)
s.split(/\s+/) // split on whitespace runs
s.search(/abc/) // first index, or -1
8. Practical Patterns
patterns.js
const patterns = {
email: /^[\w.+-]+@\w+(\.\w+)+$/,
bdPhone: /^\+?880\d{10}$/,
url: /^https?:\/\/[^\s/$.?#].[^\s]*$/i,
hex: /^#?[\da-f]{6}$/i,
ipv4: /^(?:\d{1,3}\.){3}\d{1,3}$/,
nid: /^\d{10}$|^\d{13}$|^\d{17}$/,
};
const tests = {
email: "a@x.com", bdPhone: "+8801712345678",
url: "https://abcl.tech", hex: "#39b549",
ipv4: "192.168.0.1", nid: "1234567890",
};
for (const [k, v] of Object.entries(tests)) {
console.log(k, ":", patterns[k].test(v));
}
দশ-বারোটি pattern শিখলেই বাস্তব জীবনের ৯০% কাজ চলে যায়। জটিল regex লিখতে সময় লাগে — কিন্তু পরের কেউ সেটি পড়তে পারবে কিনা তা সবসময় ভাবুন।
9. Glossary (শব্দকোষ)
| Term | Meaning | বাংলায় |
|---|---|---|
| Regex literal | /pattern/flags — preferred for fixed patterns. | /pattern/flags — fixed pattern-এর জন্য। |
| Anchor | ^ start, $ end, \b word boundary. | ^ শুরু, $ শেষ, \b word boundary। |
| Character class | Set of allowed chars: [a-z], \d, \w. | অনুমোদিত character-এর সেট। |
| Quantifier | * + ? {n,m} — how many times. | কতবার match হবে। |
| Greedy / Lazy | Match as much as possible vs as little as possible (*?). | সর্বাধিক vs সর্বনিম্ন match। |
| Capturing group | ( ) — remembered, accessible via index or name. | ( ) — আলাদা index/name-এ পাওয়া যায়। |
| Lookahead | (?=…) — assertion that doesn't consume input. | Match-এর পরে কী আসছে চেক করে কিন্তু consume করে না। |
| Lookbehind | (?<=…) — assertion before the current spot. | আগে কী ছিল সেটা চেক — consume নয়। |
| Backreference | \1 or \k<name> — repeat what a group matched. | একই group-এর match আবার মেলায়। |
| Flags | g global, i case-insensitive, u Unicode, s dotall. | g/i/u/s — global, case-insensitive, Unicode, dotall। |
সংক্ষেপে: Regex দেখতে কঠিন মনে হলেও মাত্র ১০-১২টি pattern শিখলেই বাস্তব জীবনের ৯০% কাজ চলে। জটিল regex-এ comment ও test লিখুন; HTML parsing-এ regex ব্যবহার করবেন না — DOMParser উপযুক্ত।
10. Practice Problems
- Test if a string contains "JavaScript" (case-insensitive).
✨ Show Answer
a1.jsconsole.log(/javascript/i.test("I love JavaScript!")); - Extract all numbers from a sentence.
✨ Show Answer
a2.jsconsole.log("order 42 of 99 items".match(/\d+/g)); - Replace consecutive whitespace with a single space.
✨ Show Answer
a3.jsconsole.log("hi there\n\nworld".replace(/\s+/g, " ")); - Validate a Bangladeshi phone number.
✨ Show Answer
a4.jsconsole.log(/^\+?880\d{10}$/.test("+8801712345678")); - Capture a date "YYYY-MM-DD" into named groups.
✨ Show Answer
a5.jsconst m = "2026-05-09".match(/(?<y>\d{4})-(?<mo>\d{2})-(?<d>\d{2})/); console.log(m.groups); - Find duplicated word using a backreference.
✨ Show Answer
a6.jsconsole.log(/\b(\w+)\s+\1\b/.test("the the cat")); - Strong password — at least 8 chars, 1 number, 1 symbol.
✨ Show Answer
a7.jsconst r = /^(?=.*\d)(?=.*[!@#$%^&*]).{8,}$/; ["abc", "abcdefg1", "abcdef1!"].forEach(p => console.log(p, r.test(p))); - Replace each word's first letter with a capital.
✨ Show Answer
a8.jsconsole.log("hello bangla world".replace(/\b\w/g, c => c.toUpperCase())); - Use matchAll to print every match's start index.
✨ Show Answer
a9.jsconst s = "cat sat on the mat"; for (const m of s.matchAll(/at/g)) console.log(m[0], m.index); - Use lookahead to mask a credit card except last 4.
✨ Show Answer
a10.jsconst mask = c => c.replace(/\d(?=\d{4})/g, "•"); console.log(mask("4539578763621486")); - Match Bengali numerals (০-৯) only.
✨ Show Answer
a11.jsconsole.log("১২৩ abc ৪৫".match(/[০-৯]+/g)); - Why prefer named groups over positional?
✨ Show Answer
Answer: Named groups document intent and survive pattern reordering. Positional indices break the moment someone adds a group earlier in the regex.
- Strip HTML tags using replace.
✨ Show Answer
a13.jsconsole.log("<b>Hi</b> <i>there</i>".replace(/<[^>]+>/g, ""));Real-world parsing — use a DOM parser. Regex is fine for sanitisation in trusted strings.
- Why is parsing nested HTML with regex a bad idea?
✨ Show Answer
Answer: Regex is a regular language. HTML is not — tags can nest arbitrarily deep, and quoting/escape rules vary. A regex either misses cases or matches too much. Use
DOMParserfor real HTML. - Capture username from an email address.
✨ Show Answer
a15.jsconst m = "arif.h@example.com".match(/^([\w.+-]+)@/); console.log(m?.[1]); - Test an IPv4 address with capture of each octet.
✨ Show Answer
a16.jsconst m = "192.168.0.1".match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/); console.log(m?.slice(1));
Summary — Module 32
Regex is a tiny embedded language. Learn the flag set, character classes, quantifiers, groups, and the four lookaround forms. Most real-world tasks need only ~12 patterns. Keep complex regexes commented and tested.
Regex দেখতে কঠিন মনে হয়, কিন্তু flag, class, quantifier এবং group শিখলেই ৯০% কাজ চলে। জটিল regex-এ comment ও test যোগ করুন।