"""Espressioni regolari del dominio appalti. Solo costanti (pattern compilati). I gruppi nominati (`num`, `code`, `cap`) isolano il valore da estrarre quando il match contiene un'etichetta di contesto (es. "CIG: XXXX"). """ from __future__ import annotations import re I = re.IGNORECASE U = re.UNICODE # --- Identificativi fiscali/societari --- CODICE_FISCALE = re.compile(r"\b[A-Z]{6}\d{2}[A-Z]\d{2}[A-Z]\d{3}[A-Z]\b", I) # Il prefisso "partita iva" e' opzionale; il validatore Luhn filtra i numeri # di 11 cifre non validi (riduce i falsi positivi). PARTITA_IVA = re.compile( r"(?:(?:partita\s+iva|p\.?\s?iva|piva)[\s:.]*)?\b(?P\d{11})\b", I) NUMERO_REA = re.compile(r"\bREA[\s:.n°]*([A-Z]{2}[\s-]?\d{5,7})\b", I) CCIAA = re.compile(r"\b(?:iscriz\w*\s+)?C\.?C\.?I\.?A\.?A\.?[\s:.n°]*\d{4,7}\b", I) # --- Codici gara/appalti --- CIG = re.compile(r"\bCIG[\s:.n°]*(?P[0-9A-Z]{10})\b", I) CUP = re.compile(r"\bCUP[\s:.n°]*(?P[0-9A-Z]{15})\b", I) NUMERO_GARA = re.compile( r"\b(?:numero\s+gara|n\.?\s?gara|gara\s+n\.?)[\s:.n°]*(?P[0-9]{5,9})\b", I) LOTTO = re.compile(r"\blotto[\s:.n°]*(?P[0-9]{1,4}|[IVXLCDM]+)\b", I) PROTOCOLLO = re.compile( r"\b(?:prot\w*|protocollo)[\s.:n°]*(?P\d{1,7}[/\-]?\d{0,4})\b", I) ATTO_AMMINISTRATIVO = re.compile( r"\b(?:determina(?:zione)?|delibera(?:zione)?|decreto)\s+" r"(?:dirigenziale\s+)?n\.?\s*(?P\d{1,6}[/\-]?\d{0,4})\b", I) # --- Codici di classificazione --- # CPV: 8 cifre + '-' + cifra di controllo CPV = re.compile(r"\b(?:CPV[\s:.n°]*)?(?P\d{8}-\d)\b", I) # NUTS: IT seguito da 1-3 caratteri alfanumerici NUTS = re.compile(r"\b(?PIT[A-Z0-9]{1,3})\b") ATECO = re.compile( r"\b(?:ATECO[\s:.n°]*)?(?P\d{2}\.\d{2}(?:\.\d{1,2})?)\b", I) # --- Dati finanziari/bancari --- IBAN = re.compile(r"\b[A-Z]{2}\d{2}[A-Z0-9]{11,30}\b") BIC = re.compile(r"\b[A-Z]{6}[A-Z0-9]{2}(?:[A-Z0-9]{3})?\b") CARTA_CREDITO = re.compile(r"\b(?:\d[ -]?){13,19}\b") IMPORTO = re.compile( r"(?:€|EUR|euro)\s?\d{1,3}(?:[.\s]\d{3})*(?:,\d{2})?" r"|\b\d{1,3}(?:[.\s]\d{3})*(?:,\d{2})\s?(?:€|EUR|euro)", I) RIBASSO = re.compile( r"\b(?:ribasso|sconto)[\s\w']*?(?P\d{1,3}(?:,\d{1,3})?)\s?%", I) # --- Contatti e rete --- EMAIL = re.compile(r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b") PEC = re.compile( r"\b[A-Za-z0-9._%+-]+@(?:pec\.|pec[a-z0-9-]*\.|[a-z0-9-]+\.pec\.)" r"[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b", I) TELEFONO = re.compile( r"(?:(?:tel|telefono|cell|fax|mobile)[\s.:]*)?" r"(?:\+39\s?)?(?:0\d{1,3}[\s./-]?\d{5,8}|3\d{2}[\s./-]?\d{6,7})\b", I) CAP = re.compile(r"\b(?P\d{5})\b") IP = re.compile( r"\b(?:(?:25[0-5]|2[0-4]\d|1?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|1?\d?\d)\b") MAC = re.compile(r"\b(?:[0-9A-Fa-f]{2}[:-]){5}[0-9A-Fa-f]{2}\b") # --- Previdenziali/assicurativi --- POLIZZA = re.compile( r"\bpolizza[\s\w]*?n\.?[\s:]*(?P[0-9A-Z./-]{5,20})\b", I) MATRICOLA_INPS = re.compile( r"\bmatricola[\s\w]*?[\s:]*(?P\d{6,12})\b", I) # --- Veicoli/documenti --- TARGA = re.compile(r"\b[A-Z]{2}\s?\d{3}\s?[A-Z]{2}\b")