2026-08-29 · Aervik Labs
Why regex can't catch every kind of PII
Regex reliably catches emails, phone numbers and SSNs, but it cannot recognize a name or an address without context. Why, and what closing that gap requires.
A lot of PII-redaction tooling reaches for regular expressions first, and for good reason: a handful of PII types have a genuinely fixed, or near-fixed, textual shape. But the rules that work well for an email address stop working entirely for a person’s name, and that gap isn’t a minor edge case — names and addresses are two of the most common things that show up in support transcripts, chat logs, and form submissions in the first place.
What regex handles well, and why
Some entity types really do have a shape narrow enough for a pattern match to be trustworthy:
- Email addresses — a well-defined, consistent format.
- Phone numbers — reliably matched when an explicit separator is present (a dash, dot, space, or parentheses); a bare 10-digit run with no separator is deliberately not matched, since at that point a plain number sequence is too ambiguous.
- Social Security Numbers — matched only in the standard dash-formatted shape
(
AAA-GG-SSSS). A bare 9-digit run is deliberately not treated as an SSN either — too many things (order numbers, ZIP+4 codes) share that shape for a regex to guess responsibly. - Credit card numbers — matched by digit-count patterns (15 or 16 digits in the expected groupings), and only when the digits pass the Luhn checksum every issued card number carries.
Every one of these works because the thing being matched has a structural signature that holds regardless of context. That’s the entire trick, and it’s also exactly where the trick stops working.
Where regex fundamentally can’t follow: names, addresses, and birth dates
A person’s name has no structural signature at all. “Reach out to Jane at her office” — nothing about the word “Jane” is different, character by character, from any other capitalized word in that sentence. Recognizing it as a name requires understanding what the sentence is saying, not matching a pattern in it. The same is true of a physical address: valid address formats vary enormously by country, by how someone chooses to write one out, and by what’s included (a suite number, a floor, a building name) — too many valid shapes for a pattern match to be trustworthy. A date of birth is the same problem in a different form: a regex can find a date in text without much trouble, but it has no way to tell a birth date apart from an appointment date, a contract date, or any other date sitting right next to it, without reading the surrounding sentence.
Why this matters in practice
If a redaction workflow assumes the job is done after a regex pass, names, addresses, and birth dates will pass straight through untouched — and those are frequently the fields most likely to actually identify a specific person in text that otherwise looks clean of emails and phone numbers.
How Aervik Labs’ PII Redaction API handles this
The PII Redaction API uses a contextual detection provider —
one that reads for meaning, not just pattern shape — which is asked to find seven entity
types: person names, email addresses, phone numbers, physical addresses, Social Security
Numbers, credit card numbers, and dates of birth. The model identifies which values are
sensitive; the code then deterministically locates each occurrence of that value in the real
input text itself, as written or with different letter case, spacing or digit separators, rather
than trusting the model’s own character counting, so the returned offsets always line up exactly
with the original string. A value the model reports that can’t be found in the input in any of
those forms is not given a fabricated position — and it is also
not redacted, so the response flags it in warnings and counts it in unlocated_count;
check both on every response. Neither field proves the text is clean, because a value the model
never reports cannot be counted; the patterns above run underneath the model as a floor, so a
dash-formatted SSN, a checksum-valid card number, an ASCII email address or a North American phone number written
with separators
is redacted even when the model misses it, while names, addresses and birth dates depend on the
model alone. Because every request to this API is, by
definition, text that may contain sensitive personal information, it’s also worth knowing
that Aervik Labs does not store submitted text beyond what’s needed to process the request —
no database, no logging of request bodies, and no retention of input text, output text, or
detected entities once the response is returned. Detection runs on an AI model, so the text
is sent to our model provider, Anthropic, which processes it under its own data-retention
policy. Each request also passes through RapidAPI and Cloudflare (security). The API does not detect health information. Callers that need the raw detected value scrubbed from their own logs
should redact it themselves before logging a raw API response, since entities[].value is
returned unredacted by design so you can audit exactly what was found.