Regular Expressions
Mastering regex patterns for string matching and manipulation
Challenge
Section titled “Challenge”You need to validate email addresses, extract data from strings, and transform text patterns. How do you write efficient regex patterns and apply them correctly?
Explanation
Section titled “Explanation”Regular expressions are powerful patterns for matching and manipulating strings. Understanding regex syntax, methods, and performance implications is essential for text processing.
RegExp Basics
Section titled “RegExp Basics”// Create regex patternsconst pattern1 = /hello/i; // Literal notationconst pattern2 = new RegExp('hello', 'i'); // Constructor
// Test if pattern matchesconsole.log(/test/.test('testing')); // trueconsole.log(/test/.test('hello')); // false
// Find matchesconst matches = 'hello world'.match(/\w+/g);console.log(matches); // ['hello', 'world']
// Replaceconst result = 'hello world'.replace(/world/, 'there');console.log(result); // 'hello there'Solution: Email Validation and Extraction
Section titled “Solution: Email Validation and Extraction”// Email validation (simple)const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;console.log(emailPattern.test('user@example.com')); // trueconsole.log(emailPattern.test('invalid.email')); // false
// Extract information from stringconst logLine = '2024-01-15 10:30:45 ERROR Connection failed';const timePattern = /(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/;const match = logLine.match(timePattern);
if (match) { const [full, year, month, day, hour, min, sec] = match; console.log({ year, month, day, hour, min, sec });}
// Extract all email addresses from textconst text = 'Contact admin@example.com or support@example.com';const emails = text.match(/[^\s@]+@[^\s@]+\.[^\s@]+/g);console.log(emails); // ['admin@example.com', 'support@example.com']
// Replace with captured groupsconst name = 'Doe, John';const formatted = name.replace(/(\w+),\s*(\w+)/, '$2 $1');console.log(formatted); // 'John Doe'Regex Flags and Modifiers
Section titled “Regex Flags and Modifiers”const text = 'Hello HELLO hello';
// i: Case insensitiveconsole.log(text.match(/hello/i)); // ['Hello']console.log(text.match(/hello/gi)); // ['Hello', 'HELLO', 'hello']
// g: Global (find all)console.log('cat cat cat'.match(/cat/g)); // ['cat', 'cat', 'cat']console.log('cat cat cat'.match(/cat/)); // ['cat']
// m: Multiline (^ and $ match line boundaries)const multiline = 'line1\nline2';console.log(multiline.match(/^line/m)); // ['line'] - matches first line startconsole.log(multiline.match(/^line/gm)); // ['line', 'line'] - matches all line starts
// s: Dotall (. matches newlines)console.log('a\nb'.match(/a.b/)); // nullconsole.log('a\nb'.match(/a.b/s)); // ['a\nb']Advanced Patterns
Section titled “Advanced Patterns”// Character classes/[abc]/ // a, b, or c/[^abc]/ // NOT a, b, or c/[a-z]/ // a to z/[0-9]/ // 0 to 9/\d/ // digit/\D/ // NOT digit/\w/ // word character/\W/ // NOT word character/\s/ // whitespace/\S/ // NOT whitespace
// Quantifiers/a*/ // 0 or more a's/a+/ // 1 or more a's/a?/ // 0 or 1 a/a{3}/ // exactly 3 a's/a{3,}/ // 3 or more a's/a{3,5}/ // 3 to 5 a's
// Practical patternsconst ipAddress = /^(\d{1,3}\.){3}\d{1,3}$/;const phoneNumber = /^\+?1?\s?(\d{3})[-.\s]?(\d{3})[-.\s]?(\d{4})$/;const url = /^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)$/;String Methods with Regex
Section titled “String Methods with Regex”// splitconst csv = 'John,Doe,30,john@example.com';const fields = csv.split(/,/);console.log(fields); // ['John', 'Doe', '30', 'john@example.com']
// replace with callbackconst result = 'hello world'.replace(/\w+/g, (match) => { return match.toUpperCase();});console.log(result); // 'HELLO WORLD'
// replace with groupsconst date = '2024-01-15';const formatted = date.replace(/(\d{4})-(\d{2})-(\d{2})/, '$3/$2/$1');console.log(formatted); // '15/01/2024'
// replaceAll (modern)const text = 'foo foo foo';const replaced = text.replaceAll('foo', 'bar');console.log(replaced); // 'bar bar bar'
// search - get indexconsole.log('hello world'.search(/world/)); // 6Performance Tips
Section titled “Performance Tips”// ✅ Compile regex onceconst emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;const emails = ['user@example.com', 'admin@example.com'];emails.forEach(email => emailRegex.test(email));
// ❌ Avoid: Compiling in loopemails.forEach(email => { if (/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) { }});
// ❌ Avoid: Catastrophic backtracking// This can cause performance issuesconst bad = /(x+x+)+y/; // Nested quantifiers
// ✅ Better: Use simpler patternsconst good = /x+y/;
// Test performanceconst pattern = /^[a-zA-Z0-9]{3,20}$/;const testString = 'valid-username';
console.time('regex-test');for (let i = 0; i < 1000000; i++) { pattern.test(testString);}console.timeEnd('regex-test');