xberg 1.0.0

High-performance document intelligence library for Rust. Extract text, metadata, and structured data from PDFs, Office documents, images, and 98 formats and 306 programming languages via tree-sitter code intelligence with async/sync APIs.
Documentation
//! Postal-code detection for US ZIP, UK postcode, German PLZ, French CP,
//! and Canadian FSA+LDU.
//!
//! These countries cover the majority of corpora we expect to encounter and
//! have well-defined shapes that survive regex extraction without a country
//! code in scope. Additional locales can be added without breaking changes.

use super::PatternMatch;
use crate::types::redaction::PiiCategory;
use once_cell::sync::Lazy;
use regex::Regex;

static RE_US: Lazy<Regex> = Lazy::new(|| Regex::new(r"\b\d{5}(?:-\d{4})?\b").expect("us zip regex compiles"));

static RE_UK: Lazy<Regex> =
    Lazy::new(|| Regex::new(r"\b[A-Z]{1,2}[0-9][0-9A-Z]?\s?[0-9][A-Z]{2}\b").expect("uk postcode regex compiles"));

static RE_CA: Lazy<Regex> =
    Lazy::new(|| Regex::new(r"\b[A-Z][0-9][A-Z]\s?[0-9][A-Z][0-9]\b").expect("ca postal regex compiles"));

/// Find all postal code spans in `text` (US ZIP, UK postcode, German PLZ, Canadian FSA, and more).
pub fn find_all(text: &str) -> Vec<PatternMatch> {
    let mut matches = Vec::new();

    let upper = text.to_ascii_uppercase();

    for m in RE_UK.find_iter(&upper) {
        matches.push(PatternMatch {
            start: m.start(),
            end: m.end(),
            category: PiiCategory::PostalCode,
            text: text[m.start()..m.end()].to_string(),
        });
    }
    for m in RE_CA.find_iter(&upper) {
        matches.push(PatternMatch {
            start: m.start(),
            end: m.end(),
            category: PiiCategory::PostalCode,
            text: text[m.start()..m.end()].to_string(),
        });
    }
    for m in RE_US.find_iter(text) {
        matches.push(PatternMatch {
            start: m.start(),
            end: m.end(),
            category: PiiCategory::PostalCode,
            text: m.as_str().to_string(),
        });
    }

    matches
}