Comprimento de texto
Conte um texto de cinco formas de uma vez: caracteres a olho, pontos de código (len() do Python), unidades UTF-16 (.length do JavaScript), palavras e linhas.
Por que "qual é o comprimento deste texto?" tem mais de uma resposta
Parece uma pergunta trivial, mas o comprimento de um texto depende inteiramente do que você está contando. Uma pessoa conta os caracteres que vê. Um banco de dados conta o armazenamento que um valor ocupa. O JavaScript conta algo diferente. Quando esses números não coincidem — e muitas vezes não coincidem com emojis, letras acentuadas e escritas não latinas — um único "comprimento" engana. Esta ferramenta mostra cinco medidas significativas lado a lado para que você escolha a que importa no seu caso.
As cinco métricas explicadas
- Caracteres (grafemas): o que um humano percebe como um caractere. Um emoji de família como 👨👩👧, ou uma letra com um acento combinante, conta como um — é a contagem que corresponde "a olho".
- Pontos de código (code points): o número de valores escalares Unicode. Um único caractere visível pode ser formado por vários pontos de código unidos, então esse número costuma ser maior que o de grafemas.
- Unidades UTF-16: o valor que o JavaScript reporta pela propriedade .length de uma string. Os caracteres fora do Plano Multilíngue Básico (a maioria dos emojis) ocupam duas unidades UTF-16 cada.
- Palavras: o número de tokens do tipo palavra, detectados de forma compatível com Unicode em vez de dividir ingenuamente por espaços.
- Linhas: o número de linhas, contando cada quebra de linha.
Por que emojis e acentos quebram a contagem ingênua
O texto moderno é construído com Unicode, que representa muitos caracteres visíveis como sequências em vez de unidades individuais. Um emoji de bandeira são dois símbolos indicadores regionais. Um emoji de família são várias figuras unidas por caracteres invisíveis de "junção de largura zero". Um é acentuado pode ser um único ponto de código, ou um e simples seguido de um acento combinante. Cada um parece um caractere, mas pode contar como dois, três ou mais dependendo da métrica. É exatamente por isso que contar à mão, ou confiar num único número, leva a bugs.
Qual contagem você deve usar?
- Limites de caracteres que as pessoas veem (uma bio, um campo estilo tweet, uma prévia de SMS): use Caracteres (grafemas), porque corresponde ao que o usuário conta.
- Manipulação de strings em JavaScript, indexação ou fatiamento: use unidades UTF-16, já que é nelas que .length e os índices de string se baseiam.
- Tamanhos de colunas de banco de dados: verifique se sua coluna é medida em caracteres ou em bytes — muitas são limitadas por bytes, e os bytes UTF-8 diferem de novo de todas essas contagens.
- Contagens de palavras ou linhas para editores e legibilidade: use as métricas Palavras e Linhas.
O que Python e JavaScript chamam de comprimento
Duas das cinco contagens acima são as que trazem a maioria das pessoas até esta página, e pertencem a linguagens diferentes. O len() do Python e o .length do JavaScript são descritos os dois como o comprimento de uma string, e em qualquer coisa além do ASCII puro eles respondem de formas diferentes para o mesmo texto no mesmo instante. Nenhum dos dois está errado: eles contam unidades diferentes, e as duas caixas ficam acima para que a diferença seja lida em vez de adivinhada.
- Python: len() devolve o número de pontos de código Unicode, porque uma string no Python 3 é uma sequência de pontos de código. Veja a caixa "Pontos de código" — é esse o número que len() vai te dar.
- JavaScript: .length devolve o número de unidades de código UTF-16, porque uma string de JavaScript é guardada como UTF-16. Veja a caixa "Unidades UTF-16". Já Array.from(text).length percorre a string ponto de código a ponto de código, então concorda com o Python.
- Nenhum dos dois conta o que você vê. A caixa "Caracteres" é a contagem de grafemas, e nenhum comprimento embutido dessas linguagens a produz: o JavaScript precisa de Intl.Segmenter e o Python, de um pacote de terceiros. Se o limite que você aplica é um limite que uma pessoa vai ler, essa é a caixa.
- Palavras e Linhas também não são de nenhuma das duas. As duas conseguem aproximá-las quebrando nos espaços e nas quebras de linha, e as duas se afastam das contagens mostradas aqui, que são compatíveis com Unicode — em texto escrito sem espaços, na pontuação e numa quebra de linha que encerra o texto.
O exemplo por trás de Carregar exemplo é o jeito mais rápido de ver a diferença. O emoji de família dele é um caractere para quem lê, cinco pontos de código para o Python e oito unidades UTF-16 para o JavaScript: três desses cinco pontos de código ficam fora do Plano Multilíngue Básico e custam duas unidades cada, e os dois caracteres de junção invisíveis entre eles custam uma cada. Ou seja, um campo em que alguém pode escrever vinte caracteres realmente comporta vinte a olho, enquanto uma verificação ingênua escrita em qualquer uma das duas linguagens recusa um texto que cabe.
Comprimento não é tamanho em bytes
Nenhuma das cinco contagens acima é uma contagem de bytes, e é fácil confundir as duas coisas. Uma contagem é uma propriedade do próprio texto; um tamanho em bytes é uma propriedade do texto depois de escrito em alguma codificação, então a mesma string ocupa um tamanho em UTF-8 e outro em UTF-16. O que se mede em bytes precisa, portanto, ser medido depois de codificar, e a codificação que você escolheu faz parte da resposta.
- UTF-8 é o que quase tudo usa, e tem largura variável: uma letra, um dígito ou um sinal de pontuação ASCII ocupa um byte, a maioria dos caracteres acentuados e não latinos ocupa dois ou três, e muitos emojis ocupam quatro. Cem caracteres só são cem bytes se todos eles forem ASCII — os mesmos cem caracteres em grego, hebraico, árabe ou chinês ocupam o dobro ou o triplo.
- Python: len() conta pontos de código, então codifique antes de medir. len(text.encode('utf-8')) é o número de bytes UTF-8, e nomear outro codec ali dá outro número, que é justamente o ponto.
- JavaScript: .length conta unidades UTF-16, então também não é uma contagem de bytes. new TextEncoder().encode(text).length dá o número de bytes UTF-8, no navegador e no Node, e TextEncoder só produz UTF-8, então não há codec a nomear.
- Verifique em que unidade o seu limite está escrito antes de contar qualquer coisa. Alguns bancos de dados declaram uma coluna em caracteres e outros em bytes, o valor de um cabeçalho HTTP e o tamanho de um arquivo são bytes, e uma regra escrita para pessoas é o que a caixa "Caracteres" mostra. Tudo o que se mede em caracteres já está acima; tudo o que se mede em bytes exige um comprimento depois de codificar.
Quando você já tiver a contagem de bytes, o Conversor de tamanhos de dados é onde seguir: ele transforma um número bruto de bytes nos dois sistemas de unidades ao mesmo tempo — o que se apoia em potências de mil e o que se apoia em potências de dois — e mostra como cada ferramenta da sua máquina relata o mesmo tamanho. Esta página termina onde a codificação começa; aquele começa em um número de bytes.
Perguntas frequentes
- Qual contagem corresponde ao comprimento de string do JavaScript?
- O valor de unidades UTF-16 corresponde à propriedade .length bruta do JavaScript. Se o seu código fatia ou indexa strings, é esse número que rege o comportamento dele.
- Por que um emoji conta como vários caracteres?
- Muitos emojis são compostos por vários pontos de código Unicode unidos. Como grafema (o que você vê) é um caractere, mas suas contagens de ponto de código e UTF-16 são maiores, e é por isso que cada medida é mostrada separadamente.
- Ele conta espaços e quebras de linha finais?
- Sim. Cada caractere que você cola é contado, incluindo espaços iniciais e finais e quebras de linha. Se os totais parecerem maiores do que o esperado, verifique se há espaços finais invisíveis.
- O meu texto é enviado para um servidor?
- Não. Toda a contagem acontece no seu navegador. O texto que você digita ou cola nunca sai do seu dispositivo.
- O que é um grafema?
- Um grafema, ou "cluster de grafemas", é um caractere tal como o usuário o percebe: a menor unidade que um leitor chamaria de um único caractere, mesmo que seja formada por vários pontos de código.
- Como os bytes diferem dessas contagens?
- Os bytes dependem da codificação. Em UTF-8, uma letra ASCII é um byte, a maioria dos caracteres acentuados e não latinos são dois ou três, e muitos emojis são quatro. Nenhuma das cinco métricas aqui é uma contagem de bytes, então para campos limitados por bytes codifique primeiro em UTF-8.
Ferramentas relacionadas
- Conversor de tamanhos de dados
Nenhuma das contagens daqui é um tamanho em bytes: ele só existe depois que o texto foi codificado. Com esse número em mãos, aquela página o lê em unidades decimais e binárias lado a lado e diz como cada sistema operacional vai chamá-lo.
- Testador de regex
Teste expressões regulares — correspondência, substituição, divisão.
- Diff de texto
Compare dois textos — cada linha e palavra alterada.
- Inspetor de caracteres Unicode
Veja exatamente de que caracteres um texto é feito.