Spaces:
Sleeping
Sleeping
| """ | |
| Normaliza errores típicos del OCR sobre el texto extraído de CVs. | |
| Tesseract comete errores predecibles cuando el PDF es rasterizado: | |
| caracteres similares (l/I, 0/O), separadores que se pierden ('React.js' | |
| sale como 'Reactjs'), letras que se confunden con dígitos. En vez de | |
| inflar la lista de skills con cada variante rota, normalizamos el texto | |
| ANTES de buscar entidades. | |
| Es una utilidad pura: recibe un string y devuelve un string. No conoce | |
| CVs ni NER. La tabla de equivalencias se mantiene chica a propósito — | |
| solo se agregan errores OBSERVADOS en CVs reales, no especulativos. | |
| """ | |
| import re | |
| # Mapping de "patrón roto del OCR" → "forma canónica". | |
| # La key es un regex con \b en los bordes (word boundary) para no romper | |
| # palabras que contengan el patrón como substring (ej. "Reactjs" no debe | |
| # matchear dentro de "Reactjsx"). Las keys se aplican en orden, pero como | |
| # son palabras independientes el orden no importa hoy. | |
| OCR_NORMALIZATIONS: dict[str, str] = { | |
| # React: el OCR pega "React" + "js" sin punto. | |
| r"\bReactjs\b": "React", | |
| r"\bReact\.js\b": "React", # forma canónica que SÍ vamos a tener en KNOWN_SKILLS | |
| # MaterialUI: la I mayúscula muchas veces se lee como L minúscula. | |
| r"\bMaterialUl\b": "MaterialUI", | |
| r"\bMaterial Ul\b": "MaterialUI", | |
| r"\bMaterial UI\b": "MaterialUI", | |
| # Node.js: mismo patrón que React. | |
| r"\bNodejs\b": "Node.js", | |
| # Next.js | |
| r"\bNextjs\b": "Next.js", | |
| # Vue.js | |
| r"\bVuejs\b": "Vue", | |
| } | |
| def normalize(text: str) -> str: | |
| """Aplica todas las normalizaciones OCR conocidas sobre el texto.""" | |
| for pattern, replacement in OCR_NORMALIZATIONS.items(): | |
| text = re.sub(pattern, replacement, text, flags=re.IGNORECASE) | |
| return text | |