haham7/nbc-chatbot
0
1"""2Lightweight cross-reference regex helpers (no llama_index dependency).3Kept in sync with ``NBCReferenceExtractor`` in ``retrieval_pipeline.py``.4"""5 6from __future__ import annotations7 8import re9from typing import Dict, List10 11 12class ReferencePatternExtractor:13 """Extract cross-references from NBC text using regex patterns."""14 15 CLAUSE_PATTERN = re.compile(16 r"(?:Clause|sec\.?|s\.)?\s*(\d+(?:\.\d+)*[a-z]?)", re.IGNORECASE17 )18 PART_PATTERN = re.compile(r"(?:Part|pt\.?)\s*(\d+)", re.IGNORECASE)19 TABLE_PATTERN = re.compile(r"(?:Table|tbl\.?)\s*(\d+(?:\.\d+)*)", re.IGNORECASE)20 FIGURE_PATTERN = re.compile(r"(?:Figure|Fig\.?)\s*(\d+(?:\.\d+)*)", re.IGNORECASE)21 FORMULA_PATTERN = re.compile(r"(?:Equation|eq\.?)\s*(\d+(?:\.\d+)*)", re.IGNORECASE)22 IS_PATTERN = re.compile(r"IS\s*:\s*(\d+)", re.IGNORECASE)23 NBC_PATTERN = re.compile(r"NBC\s*:\s*(\d+)", re.IGNORECASE)24 25 @classmethod26 def extract_all(cls, text: str) -> Dict[str, List[str]]:27 references = {28 "clauses": cls._normalize_clauses(cls.CLAUSE_PATTERN.findall(text)),29 "parts": cls.PART_PATTERN.findall(text),30 "tables": cls.TABLE_PATTERN.findall(text),31 "figures": cls.FIGURE_PATTERN.findall(text),32 "formulas": cls.FORMULA_PATTERN.findall(text),33 "is_codes": cls.IS_PATTERN.findall(text),34 }35 return references36 37 @classmethod38 def _normalize_clauses(cls, clauses: List[str]) -> List[str]:39 normalized = []40 for c in clauses:41 c = c.strip()42 if c and c[-1].isalpha() and not c[-2:].replace(".", "").isdigit():43 pass44 else:45 normalized.append(c.rstrip("abcdefghijklmnopqrstuvwxyz"))46 return [c for c in normalized if c] if normalized else clauses47 48 @classmethod49 def extract_clause_numbers(cls, text: str) -> List[str]:50 return cls.CLAUSE_PATTERN.findall(text)51 