正在加载,请稍候…

Regular Expressions: Practical Patterns for Real-World Problems

Master regular expressions with practical patterns. Learn lookaheads, backreferences, named groups, Unicode support, and real-world regex solutions for common tasks.

Regular Expressions: Practical Guide

Essential Patterns

// Email validation (practical, not RFC 5321 compliant)
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$/

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

// IP address (IPv4)
const ipv4Regex = /^(d{1,3}.){3}d{1,3}$/
// Stricter version with range validation
const strictIpv4Regex = /^((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]?)$/

// Phone numbers (US format)
const phoneRegex = /^(+1)?s?((d{3})|d{3})[s.-]?d{3}[s.-]?d{4}$/

// Strong password
const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*d)(?=.*[@$!%*?&])[A-Za-zd@$!%*?&]{8,}$/

// Credit card (major cards)
const creditCardRegex = /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|3[47][0-9]{13}|6(?:011|5[0-9]{2})[0-9]{12})$/

Advanced Features

// Named capture groups
const dateRegex = /(?<year>d{4})-(?<month>d{2})-(?<day>d{2})/
const match = '2026-01-15'.match(dateRegex)
const { year, month, day } = match.groups  // { year: '2026', month: '01', day: '15' }

// Lookaheads and Lookbehinds
// Positive lookahead: foo(?=bar) - foo followed by bar
const priceRegex = /d+(?=s*USD)/  // Numbers followed by USD
'100 USD 200 EUR'.match(priceRegex)  // ['100']

// Negative lookahead: foo(?!bar) - foo NOT followed by bar
const nonNegative = /d+(?!s*USD)/  // Numbers NOT followed by USD

// Positive lookbehind: (?<=foo)bar - bar preceded by foo
const afterDollar = /(?<=$)d+(?:.d{2})?/  // Numbers after $
'$100.50'.match(afterDollar)  // ['100.50']

// Negative lookbehind: (?<!foo)bar
const notAfterDollar = /(?<!$)d+/

// Non-capturing groups
const nonCapturing = /(?:https?|ftp):///

Real-World Patterns

// Parse log lines
const logRegex = /^(?<timestamp>d{4}-d{2}-d{2}T[d:.]+Z)s+(?<level>ERROR|WARN|INFO|DEBUG)s+(?<service>w+)s+-s+(?<message>.+)$/

const log = '2026-01-15T10:30:00Z ERROR auth - Login failed for user@example.com'
const { timestamp, level, service, message } = log.match(logRegex)?.groups ?? {}

// Extract query parameters
function parseQueryString(qs: string): Record<string, string> {
  const params: Record<string, string> = {}
  const regex = /[?&]?([^=]+)=([^&]*)/g
  let match
  while ((match = regex.exec(qs)) !== null) {
    params[decodeURIComponent(match[1])] = decodeURIComponent(match[2])
  }
  return params
}

// Camel case to kebab case
const toKebab = (str: string) => str
  .replace(/([a-z])([A-Z])/g, '$1-$2')
  .replace(/([A-Z]+)([A-Z][a-z])/g, '$1-$2')
  .toLowerCase()
// toKebab('camelCaseString') => 'camel-case-string'

// Truncate words (not characters)
const truncateWords = (text: string, maxWords: number) =>
  text.split(/s+/).slice(0, maxWords).join(' ') + 
  (text.split(/s+/).length > maxWords ? '...' : '')

// Remove duplicate whitespace
const normalize = (s: string) => s.replace(/s+/g, ' ').trim()

// Extract mentions and hashtags
const mentions = (text: string) => [...text.matchAll(/@(w+)/g)].map(m => m[1])
const hashtags = (text: string) => [...text.matchAll(/#(w+)/g)].map(m => m[1])

Python Regex Patterns

import re

# Compile for performance (reuse)
email_pattern = re.compile(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}
#39;) # All matches def extract_ips(text: str) -> list[str]: pattern = re.compile(r'(?:d{1,3}.){3}d{1,3}') return pattern.findall(text) # Substitution with function def mask_sensitive(text: str) -> str: def mask_email(m): parts = m.group().split('@') return parts[0][:2] + '***@' + parts[1] return re.sub(r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}', mask_email, text) # Named groups def parse_log(line: str) -> dict | None: pattern = re.compile( r'(?P<ip>d+.d+.d+.d+) .+ "(?P<method>GET|POST|PUT|DELETE) (?P<path>/S*)' ) m = pattern.search(line) return m.groupdict() if m else None # Flags text = "Hello World hello" re.findall(r'hello', text, re.IGNORECASE) # ['Hello', 'hello'] re.match(r'.*', multiline_text, re.DOTALL | re.MULTILINE)

Regex Testing and Debugging

// Create reusable validator
function createValidator(pattern: RegExp, message: string) {
  return (value: string) => ({
    valid: pattern.test(value),
    message: pattern.test(value) ? '' : message,
  })
}

const validateEmail = createValidator(
  /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$/,
  'Invalid email format'
)

// Debug complex regex
function debugRegex(pattern: RegExp, input: string) {
  const match = pattern.exec(input)
  if (!match) return { matched: false }
  
  return {
    matched: true,
    fullMatch: match[0],
    groups: match.groups,
    captures: match.slice(1),
    index: match.index,
  }
}

Common Gotchas

Issue Solution
Greedy vs lazy Use .*? for lazy
Special chars Escape with ``
Performance Compile patterns once
Catastrophic backtrack Atomic groups or possessive
Unicode Use /u flag in JS