Advanced Regular Expression Guide: Common Patterns and Performance Optimization

Advanced Regular Expression Guide: Common Patterns and Performance Optimization

Regular expressions are powerful tools for text processing, but writing efficient regular expressions requires skill. This article introduces common regular expression patterns, including email validation, URL matching, HTML tag extraction, etc., and shares techniques and common pitfalls for regular expression performance optimization.

I. Regular Expression Basic Syntax

Syntax Description Example
. Matches any character a.c matches abc
\d Matches digit \d+ matches 123
\w Matches word character \w+ matches abc_123
\s Matches whitespace \s+ matches space/tab
^ Matches start ^hello matches hello at start
$ Matches end world$ matches world at end
* Matches 0 or more times ab*c matches ac, abc, abbc
+ Matches 1 or more times ab+c matches abc, abbc
? Matches 0 or 1 time colou?r matches color, colour
{n} Matches exactly n times \d{4} matches 1234
{n,m} Matches n to m times \d{2,4} matches 12, 123, 1234
[abc] Character set, matches one of [aeiou] matches vowels
[^abc] Negated character set [^0-9] matches non-digit
(abc) Capturing group (\d+) captures digits
(?:abc) Non-capturing group (?:ab)+ does not capture
a|b Alternation cat|dog matches cat or dog
(?=abc) Positive lookahead a(?=b) matches a followed by b
(?!abc) Negative lookahead a(?!b) matches a not followed by b

II. Common Regular Expression Patterns

2.1 Email Validation

// Basic email validation
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

// Strict email validation
const strictEmailRegex = /^[a-zA-Z0-9](?:[a-zA-Z0-9._%+-]{0,61}[a-zA-Z0-9])?@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z]{2,})+$/;

// Usage example
function validateEmail(email) {
  return strictEmailRegex.test(email);
}

console.log(validateEmail('test@example.com')); // true
console.log(validateEmail('invalid@')); // false

2.2 URL Matching

// Match HTTP/HTTPS URL
const urlRegex = /https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_\+.~#?&//=]*)/;

// Extract URL components
const urlPattern = /^(https?:\/\/)?([^\/]+)(\/[^?]*)?(\?.*)?$/;

function parseUrl(url) {
  const match = url.match(urlPattern);
  if (!match) return null;
  
  return {
    protocol: match[1] || '',
    domain: match[2] || '',
    path: match[3] || '',
    query: match[4] || ''
  };
}

console.log(parseUrl('https://example.com/path?q=1'));
// { protocol: 'https://', domain: 'example.com', path: '/path', query: '?q=1' }

2.3 Phone Number Validation

// China mainland phone number
const phoneRegex = /^1[3-9]\d{9}$/;

// Support international area code
const internationalPhoneRegex = /^\+?[1-9]\d{1,14}$/;

function validatePhone(phone) {
  return phoneRegex.test(phone);
}

console.log(validatePhone('13812345678')); // true
console.log(validatePhone('1234567890')); // false

2.4 IP Address Validation

// IPv4 address validation
const ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;

// IPv6 address validation (simplified)
const ipv6Regex = /^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$/;

// Support both IPv4 and IPv6
const ipRegex = new RegExp(`(${ipv4Regex.source})|(${ipv6Regex.source})`);

function validateIP(ip) {
  return ipRegex.test(ip);
}

console.log(validateIP('192.168.1.1')); // true
console.log(validateIP('2001:0db8:85a3:0000:0000:8a2e:0370:7334')); // true

2.5 Date Format Validation

// YYYY-MM-DD format
const dateRegex = /^\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])$/;

// Format with time YYYY-MM-DD HH:MM:SS
const datetimeRegex = /^\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01]) (?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d$/;

function validateDate(dateStr) {
  if (!dateRegex.test(dateStr)) return false;
  
  // Validate date validity (e.g., Feb 30th)
  const date = new Date(dateStr);
  return date.toISOString().slice(0, 10) === dateStr;
}

console.log(validateDate('2026-07-09')); // true
console.log(validateDate('2026-02-30')); // false

2.6 HTML Tag Extraction

// Extract all HTML tags
const tagRegex = /<([a-zA-Z][a-zA-Z0-9]*)\b[^>]*>([^<]*)<\/\1>/g;

function extractTags(html) {
  const tags = [];
  let match;
  
  while ((match = tagRegex.exec(html)) !== null) {
    tags.push({
      tag: match[1],
      content: match[2]
    });
  }
  
  return tags;
}

const html = '<div>Hello</div><p>World</p>';
console.log(extractTags(html));
// [{ tag: 'div', content: 'Hello' }, { tag: 'p', content: 'World' }]

2.7 Password Strength Validation

// At least 8 chars, include uppercase, lowercase and numbers
const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,}$/;

// More complex password validation (include special chars)
const strongPasswordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/;

function checkPasswordStrength(password) {
  if (password.length < 8) return 'weak';
  if (/^[a-zA-Z]+$/.test(password)) return 'weak';
  if (/^[a-zA-Z\d]+$/.test(password)) return 'medium';
  if (/^[a-zA-Z\d@$!%*?&]+$/.test(password)) return 'strong';
  return 'unknown';
}

console.log(checkPasswordStrength('Password123!')); // strong

III. Regular Expression Performance Optimization

3.1 Avoid Greedy Matching

Use ? to make quantifiers non-greedy:

// Greedy matching (may match too much)
const greedyRegex = /
.*<\/div>/; // Lazy matching (recommended) const lazyRegex = /
.*?<\/div>/; // Example text const text = '<div>first</div><div>second</div>'; console.log(text.match(greedyRegex)); // matches entire string console.log(text.match(lazyRegex)); // matches only first div

3.2 Use Specific Character Sets Instead of Universal Characters

// Not recommended: using .* to match any character
const badRegex = /user_.*_data/;

// Recommended: using specific character set
const goodRegex = /user_[a-zA-Z0-9_]+_data/;

3.3 Use Anchors to Limit Matching Range

// Not recommended: no anchors, may match middle part
const badRegex = /test/;

// Recommended: using anchors
const startRegex = /^test/;     // match at start
const endRegex = /test$/;       // match at end
const fullRegex = /^test$/;     // exact match

3.4 Avoid Nested Quantifiers

⚠️ Warning:Nested quantifiers may cause catastrophic backtracking, seriously affecting performance.

// Dangerous: nested quantifiers
const dangerousRegex = /(a+)+b/;

// Test: this string will cause browser hang!
const testStr = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';

// Recommended: use more precise pattern
const safeRegex = /a+b/;

3.5 Use Non-Capturing Groups

// Not recommended: using capturing group when not needed
const badRegex = /(ab)+/;

// Recommended: using non-capturing group
const goodRegex = /(?:ab)+/;

3.6 Precompile Regular Expressions

// Not recommended: recompiled on each call
function validateEmailBad(email) {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}

// Recommended: precompile regex
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

function validateEmailGood(email) {
  return emailRegex.test(email);
}

3.7 Use Character Classes Instead of Alternation

// Not recommended: using alternation
const badRegex = /(cat|dog|bird)/;

// Recommended: using character class (if possible)
const goodRegex = /[cdb]at|dog|bird/;

// Better: refactor logic
const betterRegex = /(?:cat|dog|bird)/;

IV. Common Pitfalls

4.1 Special Character Escaping

In regular expressions, the following characters need to be escaped: . ^ $ * + ? ( ) [ ] { } | \

// Wrong: dot matches any character
const badRegex = /file.txt/;

// Correct: escape the dot
const goodRegex = /file\.txt/;

4.2 Multiline Mode

const text = 'line1\nline2\nline3';

// Default mode: ^ and $ match string start and end
const defaultRegex = /^line/;
console.log(text.match(defaultRegex)); // ['line1']

// Multiline mode: ^ and $ match line start and end
const multilineRegex = /^line/gm;
console.log(text.match(multilineRegex)); // ['line1', 'line2', 'line3']

4.3 Unicode Matching

// Default: does not match Unicode characters
const defaultRegex = /\w+/;
console.log('Hello'.match(defaultRegex)); // ['Hello']

// Using u flag: matches Unicode
const unicodeRegex = /\w+/u;
console.log('Hello'.match(unicodeRegex)); // ['Hello']

V. Regular Expression Testing Tools

  • Regex101: Online testing tool, supports multiple languages
  • RegExr: Interactive regex learning tool
  • Regexper: Visualize regular expressions
  • TudoSi Tools: Online regex testing tool

VI. Practical Recommendations

  • Keep it simple: Don't try to solve all problems with a single regex
  • Test thoroughly: Test various edge cases
  • Document well: Complex regex needs comments
  • Performance test: For complex patterns, perform performance testing
  • Use tools: Debug and optimize regex with online tools

πŸ’‘ Tip:Regular expressions are powerful but complex tools. For very complex text processing tasks, consider using parsers or specialized libraries instead of trying to solve them with a single regular expression.

VII. Summary

Regular expressions are one of the essential skills for developers. Mastering common patterns and performance optimization techniques can greatly improve the efficiency and reliability of text processing.

Remember, regular expressions are not a panacea. Using the right tool for the right scenario is the key to writing efficient and maintainable code.