Texto y herramientas cotidianas · Text Toolkit
Caracteres invisibles: espacios que no se separan, uniones y recortes de ancho cero
· Antecedentes
limpieza de texto Unicode publicación
Examina los caracteres que parecen nada (espacios que no se separan, espacios y uniones de ancho cero, marcas de orden de bytes) de dónde provienen, cuáles cuentan como espacios en blanco y cómo encontrarlos y eliminarlos.
Dos líneas idénticas que no están duplicadas: cómo un personaje invisible vence la deduplicación y la búsqueda
Dos líneas pueden parecer idénticas en un editor pero no superar las comprobaciones de igualdad, búsqueda o deduplicación. Uno puede contener un espacio U+0020 ordinario mientras que el otro contiene U+00A0, un espacio sin separación. Un carácter de ancho cero puede crear el mismo problema sin ocupar ningún ancho visible, dejando al editor con dos etiquetas aparentemente coincidentes que siguen siendo cadenas distintas.
Esto no es meramente cosmético. Los puntos de código ocultos pueden dividir dimensiones analíticas, anular una operación de búsqueda exacta, conservar una línea duplicada o hacer que un identificador copiado falle en la validación. Antes de reescribir el contenido a simple vista, conserve una copia de la fuente y compare sistemáticamente las cadenas sospechosas. La representación visible es evidencia de la apariencia, no prueba de que sus secuencias Unicode subyacentes coincidan.
De dónde vienen: páginas web, procesadores de texto, secuencias de emoji y copiar y pegar desde archivos PDF.
Los personajes invisibles suelen llegar a través del trabajo ordinario. Las páginas web utilizan espacios que no se separan para mantener los términos juntos, los procesadores de texto conservan el espaciado orientado al diseño y la extracción PDF reconstruye el texto a partir de glifos posicionados. Copiar entre esos sistemas puede llevar caracteres de formato a un campo CMS incluso cuando el destino solo muestra palabras y espacios familiares.
Otras marcas invisibles son partes intencionales de sistemas de escritura o emoji. Un ensamblador de ancho cero puede combinar componentes emoji en un símbolo mostrado, mientras que los ensambladores y no ensambladores afectan la forma en varios scripts. Ese origen importa: "no puedo verlo" no significa "es seguro eliminarlo". La limpieza debe centrarse en un artefacto diagnosticado, no en todos los caracteres cuyo ancho de avance sea cero.
La familia de espacios en blanco: espacios ordinarios, sin separación, estrechos e ideográficos, y lo que la versión de JavaScript considera espacios en blanco
Unicode contiene más que el espacio cotidiano. U+00A0 es el espacio no rompible, U+202F es el espacio estrecho no rompible y U+3000 es el espacio ideográfico. El manejo de espacios en blanco de JavaScript incluye estos caracteres, por lo que `trim()`, `trimStart()` y `trimEnd()` pueden eliminarlos cuando aparecen en el borde relevante de una cadena.
El recorte de líneas del Text Toolkit llama a esos métodos JavaScript en cada línea. No normaliza el espaciado interior, por lo que permanece allí un espacio sin separación entre dos palabras. Su estadística de "caracteres sin espacios" elimina los caracteres que coinciden con JavaScript `s`, que es más amplio que el espacio ASCII. Utilice ese número como una medida definida, no como una promesa de que se excluyeron todos los puntos de código invisibles.
La familia de ancho cero: espacio de ancho cero, unión y no unión, unión de palabras y marca de orden de bytes, que no son espacios en blanco en absoluto.
La familia de ancho cero sigue reglas diferentes. El espacio de ancho cero U+200B, el no ensamblador de ancho cero U+200C, el ensamblador de ancho cero U+200D y el ensamblador de palabras U+2060 son caracteres de formato en lugar de espacios en blanco de JavaScript. Por lo tanto, el `trim()` ordinario no los elimina. Una línea que contiene una de estas marcas no está en blanco simplemente porque la pantalla no muestra tinta.
U+FEFF tiene dos historias relacionadas: al comienzo de los datos codificados puede señalar una marca de orden de bytes, mientras que en el texto ha servido como un espacio sin interrupciones de ancho cero. ECMAScript incluye U+FEFF en su conjunto de espacios en blanco recortados, a diferencia de U+200B a U+200D. Por lo tanto, tratar a toda la familia de ancho cero como un tipo de espacio en blanco contradiría el comportamiento real de JavaScript.
Detectarlos: usar el contador de caracteres para detectar recuentos que no coinciden con lo que ves, recordando que algunos miembros se unen a un vecino y permanecen ocultos.
Un recuento sorprendente puede alertarle sobre contenido oculto, pero no puede identificar todos los casos. ToolAcre cuenta los grupos de grafemas con `Intl.Segmenter` cuando están disponibles. Un elemento que participa en una secuencia de emoji puede ayudar a que varios puntos de código formen un grafema, por lo que agregarlo o eliminarlo puede cambiar la representación sin producir el simple aumento de un carácter que mostraría un contador de puntos de código.
Utilice varias pistas juntas: coincidencias exactas fallidas, un resultado inesperado "sin espacios", texto copiado inspeccionado en un editor compatible con Unicode o una búsqueda de expresiones regulares para puntos de código específicos. El contador alternativo utiliza puntos de código cuando Segmenter no está disponible, por lo que los resultados también pueden diferir según la capacidad del navegador. El conteo reduce la investigación; no es un escáner de caracteres ocultos ni un visor de nombres Unicode.
Detección de personajes ocultos: los recuentos proporcionan pistas, no un inventario completo
Para obtener un artefacto de copiar y pegar confirmado, trabaje en un duplicado y abra Buscar y reemplazar en modo de expresión regular. Al buscar `[]` y reemplazarlo con nada, se eliminan los espacios de ancho cero y los caracteres U+FEFF incrustados en todo el texto. La herramienta compila el patrón con el indicador global de JavaScript, informa el recuento de reemplazos y deja el texto sin cambios si el patrón no es válido.
No amplíe automáticamente ese patrón a `[-]`. El rango también elimina U+200C y U+200D, que pueden cambiar la forma del guión y dividir un emoji unido en símbolos separados. Agregue esos puntos de código solo cuando la inspección demuestre que no son deseados. Después del reemplazo, ejecute la deduplicación y compare el resultado con el original conservado antes de publicarlo.
Ejemplo resuelto: eliminar solo los caracteres de ancho cero no deseados confirmados antes de eliminar los duplicados
Esta limpieza no aborda los caracteres de control bidireccional, los homoglifos ni todos los problemas de seguridad asociados con el texto confuso. Las marcas direccionales pueden alterar el orden visual, mientras que los ataques de homoglifos utilizan diferentes caracteres visibles que se parecen entre sí. Ninguno de los problemas se resuelve eliminando espacios, y una expresión regular indiscriminada de caracteres invisibles puede dañar el contenido multilingüe legítimo sin abordar el riesgo real.
El kit de herramientas tampoco expone indicadores de expresiones regulares como Unicode o modo multilínea, no resalta cada próxima partida ni muestra los reemplazos individualmente. Reemplazar todo opera en todo el texto, por lo que el recuento informado y la acción Deshacer son salvaguardias importantes. Para código fuente, copia legal o scripts desconocidos, inspeccione cada carácter con una herramienta Unicode dedicada antes de realizar ediciones masivas.
La conclusión: invisible no significa inofensivo; El contador del Text Toolkit y la función de búsqueda y reemplazo de expresiones regulares los exponen y los eliminan sin salir del navegador.
Invisible no significa vacío, intercambiable o dañino. Los espacios que no se separan son espacios en blanco con semántica de diseño; los ensambladores de ancho cero pueden llevar semántica de conformación; U+FEFF vuelve a comportarse de forma diferente cuando se recorta JavaScript. La limpieza precisa comienza nombrando el punto del código, entendiendo por qué puede estar presente y decidiendo si el destino aún necesita su función.
Utilice Text Toolkit como un banco de trabajo controlado en el lado del navegador: los recuentos pueden exponer una discrepancia, la búsqueda y reemplazo de expresiones regulares puede eliminar un conjunto definido con precisión y la deduplicación puede confirmar que las diferencias ocultas han desaparecido. Conserve un original, evite eliminar uniones de forma predeterminada y verifique el resultado renderizado. Una corrección estrecha y revisable es más segura que tratar todo Unicode invisible como basura.