import re


def filter_addresses_and_numbers(stack_frame):
  """Return a normalized string without unique addresses and numbers."""
  # Remove offset part from end of every line.
  result = re.sub(r'\+0x[0-9a-fA-F]+\n', '\n', stack_frame, re.DOTALL)

  # Replace sections that appear to be addresses with the string "ADDRESS".
  address_expression = r'0x[a-fA-F0-9]{4,}[U]*'
  address_replacement = r'ADDRESS'
  result = re.sub(address_expression, address_replacement, result)

  # Replace sections that appear to be numbers with the string "NUMBER".
  # Cases that we are avoiding:
  # - source.cc:1234
  # - libsomething-1.0.so (to avoid things like NUMBERso in replacements)
  number_expression = r'(^|[^:0-9.])[0-9.]{4,}($|[^A-Za-z0-9.])'
  number_replacement = r'\1NUMBER\2'
  return re.sub(number_expression, number_replacement, result)