Address Detection for Any Language
How OGuardAI detects addresses across languages, and how to extend detection to any locale without recompiling
OGuardAI detects and tokenizes addresses in any language, and you can extend structural detection to any locale through configuration, with no code change and no hardcoded ceiling.
The layers
- NER (language-agnostic). The advanced NER detector recognizes addresses in text of any language and tokenizes them. This is the primary path and needs no per-locale configuration.
- Built-in regex floor. A set of built-in address patterns ships for DE, US, FR, IT, ES, NL, and UK, giving high-precision detection for those common formats even without NER.
- Config-declared locale patterns.
detector.vocab.extra_pattern_specs(and the simplerextra_patterns) let you add address regex for any locale. Overlays are additive (they can only add spans, never suppress a built-in one) and fail closed (invalid config aborts startup).
Detection is the protection boundary: once an address is detected and tokenized, policy controls how (or whether) it is restored. Component-level structural parsing (splitting street/city) is a restore-quality feature, not required for protection.
Adding a locale
The ready-to-use examples/address-locale-pack.yaml extends the floor to JP, CN, KR, BR (CEP), IN (PIN), RU, PL, and SE. Merge its detector.vocab.extra_pattern_specs.address list into your oguardai.yaml, or add your own:
detector:
vocab:
extra_pattern_specs:
address:
# A distinctive marker needs no gating.
- pattern: '〒\d{3}-\d{4}' # Japan postal code
description: "JP postal"
# A broad shape is gated on a nearby address keyword so it does not over-detect.
- pattern: '\d{2}-\d{3}' # Poland postal (NN-NNN)
context_required: true
context_words: ["adres", "kod pocztowy"]Each spec accepts:
| Field | Meaning |
|---|---|
pattern | The regex (linear-time Rust regex; length-capped). Required. |
confidence | Base confidence in [0, 1] (default 0.8). |
context_words | Boost/gate words for this pattern. |
context_required | Only emit a match when a context_word is within the window. Requires non-empty context_words. |
context_window_chars | Override the gate window (characters). |
value_group | Tokenize only this capture group (validated against the regex, fail closed). |
description | Operator note, ignored by the engine. |
extra_patterns (a bare list of regex strings per label) still works for simple cases; extra_pattern_specs adds context gating and capture-group scoping, which is what broad address shapes need.
Regex safety rules
- Anchor broad shapes. A pattern that matches arbitrary text (for example
\d+,\w+,.*, or[A-Za-z]+) is rejected at startup. A fixed-width shape like\d{5}is accepted, but it over-detects every 5-digit run, so still anchor it on a script-specific postal marker (〒,邮编,индекс,CEP,PIN) or setcontext_required: truewithcontext_wordsso it only fires near an address keyword. - Avoid
\bfor CJK/Thai. Word boundaries do not behave as expected across scripts; anchor on markers, punctuation, or bounded character classes instead. - Keep it conservative. Prefer postal markers and address keywords with bounded tails over "anything after the city". Overlays are additive, so a narrow pattern that misses is safer than a broad one that over-detects.
- Bounds are enforced. Pattern length, patterns-per-entity, and entity-type counts are capped; an invalid regex, an out-of-range
value_group, orcontext_requiredwithoutcontext_wordsaborts startup rather than degrading silently.
Testing a new locale
- Add the spec to
detector.vocab.extra_pattern_specs.address. - Start the server (it fails closed if the config is invalid).
POST /v1/detectwith a representative sample and confirm anaddressentity is returned with the expected span.- Confirm a non-address sample of the same shape is NOT matched (tune
context_requiredif it over-detects).
Languages
How OGuardAI protects data in any language, how to use a language, and how to extend detection and restoration to new ones
Plugin and Extension Development
The real extension seams in OGuardAI, custom entities in policy, language pack overlays, and the NER backend interface, plus how to build and test a change