Una clave que es evidentemente correcta no coincide. Un cruce no devuelve nada. Una cadena de traducción sale como ausente mientras la estás mirando. Copias los dos valores a un editor de texto y siguen siendo idénticos.
No son idénticos. Uno de ellos lleva un carácter que no ocupa espacio y no dibuja nada, y a la comparación de cadenas le da igual que tú no puedas verlo.
¿Qué caracteres cuentan como invisibles?
Hay una lista concreta, y es más corta de lo que parece. Agrupados por para qué se diseñaron:
U+00A0espacio duro — un espacio por el que navegadores y procesadores de texto no cortan la línea. Se ve exactamente igual que un espacio normal y es un carácter distinto.U+00ADguion blando — una pista sobre dónde se puede partir una palabra. Invisible salvo que la línea corte justo ahí.U+200Bespacio de ancho cero yU+2060unión de palabras — pistas de corte de línea sin ancho ninguno.U+200Cno-unión de ancho cero yU+200Dunión de ancho cero — controlan cómo enlazan las letras contiguas. Son legítimos en árabe y persa, yU+200Des además lo que pega las secuencias de emoji modernas.U+200E/U+200Fmarcas de dirección yU+202A–U+202Econtroles de incrustación y anulación — fuerzan la dirección del texto en contenido mixto de izquierda a derecha y de derecha a izquierda.U+FEFF— la marca de orden de bytes cuando está al principio del archivo, y un espacio de ancho cero sin corte en cualquier otro sitio.U+3000espacio ideográfico — el espacio de ancho completo de la composición china, japonesa y coreana. Este sí se ve; simplemente no es el espacio que crees.
De dónde sale cada uno
Conocer la procedencia importa, porque te dice cuántos más tienes.
Pegar desde una página web o un procesador de texto trae espacios duros. Quien escribe HTML los usa para separar cosas, y el pegado se los lleva. Si te llegó uno por esta vía, tienes tantos como tuviera el origen.
Pegar desde un PDF trae guiones blandos y espacios de ancho cero, porque el motor de maquetación los puso ahí para justificar el texto y la extracción los entregó junto con todo lo demás.
El contenido de derecha a izquierda trae marcas de dirección, a menudo añadidas por quien lo escribió para que el texto mixto de árabe y latino se viera bien en su editor. Estaban resolviendo un problema real; lo que no debía era sobrevivir hasta una clave.
Un archivo concatenado de varias exportaciones trae U+FEFF en mitad del contenido: cada parte tenía su propia marca de orden de bytes, y solo la primera quedó al principio.
El texto CJK escrito con un método de entrada trae espacios ideográficos, porque esa es la tecla de espacio.
Por qué no se ve nada raro
La comparación de cadenas es carácter a carácter. "item_mug" y "item_mug" tienen distinta longitud, así que no son iguales, y no hay más misterio que ese. Ninguna búsqueda, cruce, diccionario ni === los va a tratar como lo mismo.
Lo que lo convierte en un enigma es que todas las capas que usas para investigarlo esconden la prueba. La terminal no dibuja nada. El navegador no dibuja nada. Un diff enseña dos líneas que parecen iguales. Copiar el valor se lleva el carácter con él, así que pegarlo en otro sitio reproduce el problema en vez de destaparlo.
Por eso tampoco basta con «haz un trim». trim() quita espacios en blanco, y la mayoría de estos caracteres no son espacio en blanco según esa definición: un espacio de ancho cero sobrevive intacto a un recorte.
Un fallo emparentado que no está en la lista de arriba: dos valores pueden diferir por normalización Unicode y no por un carácter invisible. é puede ser un solo punto de código o una e seguida de un acento combinante, y esas son cadenas distintas que se dibujan igual. Nada de la familia de los invisibles encuentra esa, porque ambas formas son visibles; eso necesita una pasada de normalización.
El que normalmente no es un error
El espacio ideográfico, U+3000, merece un trato aparte, y el editor de este sitio lo clasifica distinto que a los demás por eso mismo: lo reporta como información y no como aviso.
En texto chino, japonés y coreano, un espacio de ancho completo suele ser exactamente lo que su autor quería. Es el espacio correcto para esa escritura, sale del método de entrada estándar, y quitarlo cambia el texto.
Así que conviene saber que está ahí —un espacio de ancho completo en una columna de identificadores casi seguro que está mal— mientras que un «quita todos los espacios de este tipo» sobre un archivo de descripciones en japonés estropearía el contenido en silencio. La distinción no es si el carácter es sospechoso, sino en qué columna ha aparecido.
Encontrarlos y quitarlos
El requisito es una herramienta que los dibuje, porque por definición no puedes buscar algo que no ves ni puedes teclear. Una vez los ves, el orden es:
- Encuentra todas las apariciones, no la que se rompió. El valor que falló es el que notaste, no el único afectado. Lo que pegó un espacio duro una vez lo pegó cincuenta.
- Decide por clase de carácter, no por celda. Los de ancho cero en una columna de claves siempre sobran. Los espacios duros normalmente quieren convertirse en espacios normales, no desaparecer. Los ideográficos en texto descriptivo deben quedarse.
- Aplícalo sobre todo el archivo en una sola operación, para que el resultado sea coherente y reversible de una vez.
- Vuelve a revisar después. Quitar un espacio de ancho cero puede destapar un espacio normal al final que se escondía detrás.
Para el conjunto más amplio de averías, cómo arreglar un TSV roto coloca esta en su sitio entre las demás: codificación primero, estructura después, caracteres al final.
Hacerlo aquí
El editor de este sitio dibuja los espacios en la rejilla donde están, así que un espacio final es algo que se ve, no algo que se deduce. Los caracteres invisibles se reportan con su punto de código exacto, contados por celda, y el recuento del inspector de celda sale de la misma función que el del panel de revisión — dos definiciones de «invisible» acabarían discrepando, y esta es justo la función donde eso no puede pasar.
Cada clase es un hallazgo aparte que puedes arreglar en todo el archivo dentro de un único paso de deshacer, así que probar uno no cuesta nada. El espacio ideográfico se reporta como información y no como error, porque en una columna de texto japonés probablemente esté bien.
No se sube nada: el archivo lo lee, lo revisa y lo escribe tu navegador.