Longitud de texto
Cuenta un texto de cinco formas: caracteres a la vista, puntos de código (len() de Python), unidades UTF-16 (.length de JavaScript), palabras y líneas.
Por qué "¿qué longitud tiene este texto?" tiene más de una respuesta
Suena como una pregunta trivial, pero la longitud de un fragmento de texto depende por completo de qué estés contando. Una persona cuenta los caracteres que ve. Una base de datos cuenta el almacenamiento que ocupa un valor. JavaScript cuenta algo distinto. Cuando estos números no coinciden —y a menudo no lo hacen con emojis, letras acentuadas y escrituras no latinas— una sola "longitud" induce a error. Esta herramienta muestra cinco medidas significativas una junto a otra para que elijas la que importa en tu caso.
Las cinco métricas explicadas
- Caracteres (grafemas): lo que un humano percibe como un carácter. Un emoji de familia como 👨👩👧, o una letra con un acento combinante, cuenta como uno: es el recuento que coincide "a simple vista".
- Puntos de código (code points): el número de valores escalares Unicode. Un único carácter visible puede estar formado por varios puntos de código unidos, así que este número suele ser mayor que el de grafemas.
- Unidades UTF-16: el valor que JavaScript reporta desde la propiedad .length de una cadena. Los caracteres fuera del Plano Multilingüe Básico (la mayoría de los emojis) ocupan dos unidades UTF-16 cada uno.
- Palabras: el número de tokens de tipo palabra, detectados de forma compatible con Unicode en lugar de dividir ingenuamente por espacios.
- Líneas: el número de líneas, contando cada salto de línea.
Por qué los emojis y los acentos rompen el conteo ingenuo
El texto moderno se construye con Unicode, que representa muchos caracteres visibles como secuencias en lugar de unidades individuales. Un emoji de bandera son dos símbolos indicadores regionales. Un emoji de familia son varias figuras unidas por caracteres invisibles de "unión de ancho cero". Una é acentuada puede ser un único punto de código, o una e simple seguida de un acento combinante. Cada uno de ellos parece un carácter pero puede contar como dos, tres o más según la métrica. Por eso contar a mano, o fiarse de un solo número, provoca errores.
¿Qué recuento deberías usar?
- Límites de caracteres que ve la gente (una biografía, un campo estilo tuit, una vista previa de SMS): usa Caracteres (grafemas), porque coincide con lo que cuenta el usuario.
- Manejo de cadenas en JavaScript, indexado o troceado: usa unidades UTF-16, ya que es sobre lo que se basan .length y los índices de cadena.
- Tamaños de columnas de base de datos: comprueba si tu columna se mide en caracteres o en bytes; muchas están limitadas por bytes, y los bytes UTF-8 difieren de nuevo de todos estos recuentos.
- Recuentos de palabras o líneas para editores y legibilidad: usa las métricas de Palabras y Líneas.
Qué entienden por "longitud" Python y JavaScript
Dos de los cinco recuentos de arriba son los que traen aquí a la mayoría de la gente, y pertenecen a lenguajes distintos. len() en Python y .length en JavaScript se describen los dos como la longitud de una cadena, y con cualquier cosa que pase del ASCII simple responden distinto para el mismo texto en el mismo instante. Ninguno se equivoca: cuentan unidades diferentes, y arriba están las dos casillas para que la diferencia se lea en lugar de suponerse.
- Python: len() devuelve el número de puntos de código Unicode, porque una cadena en Python 3 es una secuencia de puntos de código. Mira la casilla "Puntos de código": ese es el número que te dará len().
- JavaScript: .length devuelve el número de unidades de código UTF-16, porque una cadena de JavaScript se guarda como UTF-16. Mira la casilla "Unidades UTF-16". En cambio, Array.from(text).length recorre la cadena por puntos de código, así que coincide con Python.
- Ninguno de los dos cuenta lo que ves. La casilla "Caracteres" es el recuento de grafemas, y ninguna longitud incorporada de estos lenguajes la produce: JavaScript necesita Intl.Segmenter y Python un paquete de terceros. Si el límite que aplicas es uno que va a leer una persona, esa es la casilla.
- Palabras y Líneas tampoco son de ninguno de los dos. Ambos pueden aproximarlas partiendo por espacios y por saltos de línea, y ambos se separan de los recuentos de aquí, que son compatibles con Unicode: con texto escrito sin espacios, con la puntuación y con un salto de línea que cierra el texto.
El ejemplo que hay detrás de Cargar ejemplo es la forma más rápida de verlo. Su emoji de familia es un carácter para quien lee, cinco puntos de código para Python y ocho unidades UTF-16 para JavaScript: tres de esos cinco puntos de código quedan fuera del Plano Multilingüe Básico y cuestan dos unidades cada uno, y los dos enlaces invisibles entre ellos cuestan uno cada uno. Así, un campo donde alguien puede escribir veinte caracteres admite de verdad veinte a la vista, mientras que una comprobación ingenua escrita en cualquiera de los dos lenguajes rechaza texto que cabe.
La longitud no es el tamaño en bytes
Ninguno de los cinco recuentos de arriba es un recuento de bytes, y confundirlos es fácil. Un recuento es una propiedad del texto en sí; un tamaño en bytes es una propiedad del texto una vez escrito en alguna codificación, así que una misma cadena ocupa un tamaño en UTF-8 y otro distinto en UTF-16. Lo que se mide en bytes hay que medirlo, por tanto, después de codificar, y qué codificación elegiste forma parte de la respuesta.
- UTF-8 es lo que usa casi todo, y es de ancho variable: una letra, un dígito o un signo de puntuación ASCII ocupa un byte, la mayoría de los caracteres acentuados y no latinos ocupan dos o tres, y muchos emojis ocupan cuatro. Cien caracteres son cien bytes solo si todos ellos son ASCII: esos mismos cien caracteres en griego, hebreo, árabe o chino ocupan el doble o el triple.
- Python: len() cuenta puntos de código, así que codifica antes de medir. len(text.encode('utf-8')) es el número de bytes UTF-8, y nombrar ahí otro códec da otro número, que es justo de lo que se trata.
- JavaScript: .length cuenta unidades UTF-16, así que tampoco es un recuento de bytes. new TextEncoder().encode(text).length da el número de bytes UTF-8, tanto en el navegador como en Node, y TextEncoder solo produce UTF-8, así que no hay códec que nombrar.
- Comprueba en qué unidad está escrito tu límite antes de contar nada. Algunos motores de base de datos declaran una columna en caracteres y otros en bytes, el valor de una cabecera HTTP y el tamaño de un archivo son bytes, y una regla escrita para personas es lo que muestra la casilla "Caracteres". Todo lo que se mide en caracteres ya está arriba; todo lo que se mide en bytes necesita una longitud ya codificada.
Cuando ya tengas un recuento de bytes, el Conversor de tamaños de datos es donde seguir: convierte un número bruto de bytes a los dos sistemas de unidades a la vez —el que se apoya en potencias de mil y el que se apoya en potencias de dos— y muestra cómo informará del mismo tamaño cada herramienta de tu equipo. Esta página termina donde empieza la codificación; aquella empieza en un número de bytes.
Preguntas frecuentes
- ¿Qué recuento coincide con la longitud de cadena de JavaScript?
- El valor de unidades UTF-16 coincide con la propiedad .length en bruto de JavaScript. Si tu código trocea o indexa cadenas, este es el número que rige su comportamiento.
- ¿Por qué un emoji cuenta como varios caracteres?
- Muchos emojis están compuestos por varios puntos de código Unicode unidos. Como grafema (lo que ves) es un carácter, pero sus recuentos de puntos de código y UTF-16 son mayores, y por eso cada medida se muestra por separado.
- ¿Cuenta los espacios y saltos de línea finales?
- Sí. Se cuenta cada carácter que pegas, incluidos los espacios iniciales y finales y los saltos de línea. Si los totales parecen más altos de lo esperado, revisa si hay espacios finales invisibles.
- ¿Se envía mi texto a un servidor?
- No. Todo el conteo ocurre en tu navegador. El texto que escribes o pegas nunca sale de tu dispositivo.
- ¿Qué es un grafema?
- Un grafema, o "clúster de grafemas", es un carácter tal como lo percibe el usuario: la unidad más pequeña que un lector llamaría un solo carácter, aunque esté formada por varios puntos de código.
- ¿En qué se diferencian los bytes de estos recuentos?
- Los bytes dependen de la codificación. En UTF-8, una letra ASCII es un byte, la mayoría de los caracteres acentuados y no latinos son dos o tres, y muchos emojis son cuatro. Ninguna de las cinco métricas de aquí es un recuento de bytes, así que para campos limitados por bytes conviene codificar primero a UTF-8.
Herramientas relacionadas
- Conversor de tamaños de datos
Ninguno de los recuentos de aquí es un tamaño en bytes: eso solo existe cuando el texto ya está codificado. Con ese número en la mano, esa página lo lee en unidades decimales y binarias a la vez y dice cómo lo llamará cada sistema operativo.
- Probador de regex
Prueba expresiones regulares — coincidencia, reemplazo y división.
- Comparador de textos
Compara dos textos — cada línea y palabra cambiada.
- Inspector de caracteres Unicode
Descubre exactamente de qué caracteres se compone un texto.