Modules
A catalog of personal identifiers, each a regex plus, where the identifier has one, a check-digit or structure validator, and a scanner that finds them in a text, most of them in one shared regex pass.
One match in a text.
One identifier in the catalog: a regex that finds values of its shape, and the check a value must pass before it counts.
The catalog itself: every identifier as a PiiCatalog.Pattern.
Raised by PiiCatalog.scan/2 and PiiCatalog.find/2 when the regex
engine stops before it has scanned the whole text, for example when a
pattern reaches the engine's match limit (:match_limit) on a crafted
input.
A compiled set of patterns, ready to scan text. Build one with
PiiCatalog.compile/1 and keep it: compiling every pattern takes about
as long as scanning a few kilobytes of text, which is worth paying once rather
than per call. A scanner is an immutable value, so it can be kept in a process, an ETS
table or :persistent_term. Build it at runtime rather than in a module
attribute: from OTP 28 a compiled regex is a reference, which cannot be
stored at compile time.
Checks a candidate match must pass before it counts.
National identity, tax and social security numbers: the checks for
:pesel_pl, :rrn_be, :ppsn_ie, :nif_pt, :ahv_ch, :svnr_at,
:isikukood_ee and :nhs_gb.
EU VAT identification numbers, for the 27 member states.