============================================================
 REGULAR EXPRESSIONS — TEXT PATTERN EXTRACTOR - Demo Run
============================================================

--- Email extraction ---
  ['support@example.com', 'sales@company.org']

--- Phone number extraction ---
  ['(555) 123-4567', '555-987-6543']

--- Phone redaction (re.sub) ---
  Contact us at support@example.com or sales@company.org. Call [REDACTED] or [REDACTED] for assistance. Meeting scheduled for 2026-03-15.

--- Date extraction with named groups ---
  {'year': '2026', 'month': '03', 'day': '15'}

--- match() vs search() ---
  re.match(r'\d{4}', ...) = None  (fails: string doesn't START with digits)
  re.search(r'\d{4}', ...) = <re.Match object; span=(23, 27), match='2026'>  (succeeds: finds digits anywhere)

--- Greedy vs. non-greedy matching ---
  Greedy <.+>:      ['<b>bold</b> and <i>italic</i>']  (matched across BOTH tags at once)
  Non-greedy <.+?>: ['<b>', '</b>', '<i>', '</i>']  (matched each tag separately)

--- Compiled pattern reuse ---
  EMAIL_PATTERN was compiled once and reused across all extract_emails() calls above --
  faster than re.findall(pattern_string, text) when used many times.

============================================================
 Assignment: extract_log_entries with named groups
============================================================
  {'date': '2026-01-15', 'time': '08:00:00', 'level': 'INFO', 'message': 'Server started'}
  {'date': '2026-01-15', 'time': '08:03:00', 'level': 'WARNING', 'message': 'High memory usage'}
  {'date': '2026-01-15', 'time': '08:39:00', 'level': 'ERROR', 'message': 'Database unreachable'}
