7. Strip Email Signature / Boilerplate from a Message
Problem
When a customer replies over email, the raw body Fin receives usually includes a trailing signature block ("Best regards, John") or other client-added boilerplate stacked after the actual message. That trailing content is irrelevant to the customer's question and can confuse a model if it's sent along as-is, so it needs to be trimmed off before the message reaches the answering pipeline.
Write a function that takes the raw email body and returns it with any trailing signature/boilerplate removed, leaving only the substantive message.
Source: src/7_strip_email_signature.py
def strip_signature(email_body: str) -> str
>>> strip_signature("My order hasn't arrived yet.\nBest regards,\nJohn")
"My order hasn't arrived yet."
>>> strip_signature("I love your product and use it daily.")
'I love your product and use it daily.'
Step-by-Step Approach
- Define a small set of known signature markers: exact-match lines like an email "signature delimiter" (
--), and case-insensitive line prefixes like "best regards", "kind regards", "sent from my", "thanks,", "cheers,". - Split the email body into lines and scan top-to-bottom, since a signature block is always trailing content — the first marker hit is the boundary.
- For each line, check the exact-match set first (a signature delimiter line is exactly "--" or "-- ", not merely a line containing those characters).
- Then lower-case the line and check whether it starts with any of the prefix markers.
- The moment either check hits, truncate the body to everything before that line, strip surrounding whitespace, and return it.
- If no marker is ever found, the whole body is legitimate message content — return it stripped, unchanged.
The key insight is treating this as a boundary-finding problem, not a filtering problem: once you find the first signature marker, everything after it is discarded wholesale, so a single linear scan with early return is both correct and efficient.
Reference solution
SIGNATURE_EXACT_MARKERS = {"--", "-- "}
SIGNATURE_PREFIX_MARKERS = (
"best regards",
"kind regards",
"sent from my",
"thanks,",
"cheers,",
)
def strip_signature(email_body: str) -> str:
# Scan lines top-to-bottom for the first signature marker, truncate there. O(n) lines.
lines = email_body.split("\n")
# enumerate gives index i for slicing
for i, line in enumerate(lines):
# O(1) set membership, exact match only
if line in SIGNATURE_EXACT_MARKERS:
return "\n".join(lines[:i]).strip()
# normalize case before prefix check
lower = line.lower()
# startswith, not substring
if any(lower.startswith(marker) for marker in SIGNATURE_PREFIX_MARKERS):
return "\n".join(lines[:i]).strip()
return email_body.strip()
Key Functions & Tricks
{"--", "-- "}— set literal for O(1) exact-match membership testing(...)tuple — ordered constants, iterated viaany(...)not membership-testedstr.split("\n")— breaks body into lines for indexed scan and reassemblyenumerate(lines)— yields(index, value)pairs in one passstr.lower()— case-normalizes before the prefix check onlyany(lower.startswith(marker) for marker in ...)— short-circuits on first matchlines[:i]— slice of every line before the signature, excluding itstr.strip()— trims whitespace on every return path for consistent output
How to Recognize This Pattern
Reach for a marker-based boundary scan whenever you need to strip a known-format trailer (signature, footer, disclaimer, quoted-reply chain) from otherwise free-form text — the shape is always "scan for the first occurrence of a known marker, then everything after it is discarded." A common variation is scanning from the bottom up instead when the marker set is ambiguous mid-body but reliable near the end (e.g. quoted "On <date>, X wrote:" reply chains). A common pitfall is using a substring check where an exact-match or prefix check is required — for example, a body line that happens to contain "thanks," mid-sentence rather than starting with it would be wrongly treated as a signature marker if you check for containment instead of a line prefix.