Menu

Strings em Golang: Split, Join, Contains, Replace e mais

Trabalhando com strings em Go: o pacote strings (Split, Join, Contains, Replace, Fields, TrimSpace, ToUpper), montar strings com eficiência usando strings.Builder, raw strings de várias linhas, imutabilidade e por que len conta bytes.

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

Uma string em Go é uma sequência imutável de bytes, normalmente texto UTF-8. Os operadores trabalham sobre a própria string (+, ==, <, indexação, fatiamento), e todo o resto fica no pacote padrão strings.

Dividindo strings

FunçãoDivide emObservações
Split(s, sep)cada sepmantém partes vazias; Split("", ",") devolve [""], uma string vazia
SplitN(s, sep, n)no máximo n partesa última parte guarda o resto
SplitAfter(s, sep)cada sepmantém o separador em cada parte
Fields(s)sequências de espaço em branconunca devolve partes vazias
FieldsFunc(s, f)caracteres em que f é trueseparadores personalizados
Cut(s, sep)só o primeiro sepdevolve antes, depois e se encontrou (Go 1.18)

O caso Split("", ",") pega muita gente: uma entrada vazia gera um slice de tamanho 1, não 0. Ao dividir entrada do usuário, usar Fields ou verificar s == "" antes evita um elemento vazio fantasma.

strings.Cut é o jeito mais limpo de dividir chave=valor, usuario@host e pares parecidos. O Go 1.24 também trouxe versões com iterador, strings.SplitSeq e strings.FieldsSeq, que entregam as partes uma a uma sem montar um slice.

Buscando

FunçãoDevolve
Contains(s, sub)true se sub aparece em s
ContainsAny(s, chars)true se algum caractere de chars aparece
HasPrefix(s, p) / HasSuffix(s, p)true se s começa ou termina com p
Index(s, sub)posição em bytes da primeira ocorrência, ou -1
LastIndex(s, sub)posição em bytes da última ocorrência, ou -1
Count(s, sub)número de ocorrências sem sobreposição
EqualFold(a, b)igualdade sem diferenciar maiúsculas e minúsculas

Toda busca diferencia maiúsculas de minúsculas, exceto EqualFold. Para buscar sem diferenciar, passe os dois lados para minúsculas ou use EqualFold em comparações de string inteira.

Transformando

Uma armadilha: Trim, TrimLeft e TrimRight recebem um conjunto de caracteres, não um prefixo. strings.TrimLeft("abcab", "ab") remove todos os a e b do começo e devolve "cab". Para remover um prefixo ou sufixo exato, use TrimPrefix e TrimSuffix.

Concatenação e strings.Builder

+ junta strings, e fmt.Sprintf formata valores em uma só. Os dois alocam uma string nova a cada vez, porque strings são imutáveis. Isso não é problema para poucas operações e é lento dentro de um laço, em que cada += copia tudo o que já foi montado. Use strings.Builder no lugar:

Um strings.Builder zero já está pronto para uso. Ele implementa io.Writer, então fmt.Fprintf escreve direto nele. Chame b.Grow(n) antes se você souber mais ou menos o tamanho do resultado. Não copie um Builder depois de escrever nele; passe um ponteiro.

Strings multilinha e raw strings

Go tem dois tipos de literal de string:

Strings entre aspas duplas processam escapes (\n, \t, \", \\, \u00e9) e precisam caber em uma linha. Raw strings entre crases tomam tudo ao pé da letra, incluindo quebras de linha, e por isso são a forma de escrever strings multilinha, expressões regulares, JSON e caminhos do Windows. Uma raw string não pode conter crase, e os retornos de carro (carriage return) dentro dela são descartados. Repare que a query acima começa com uma quebra de linha, já que o literal começa logo depois da crase de abertura.

Tamanho, indexação e substrings

len(s) é o número de bytes. s[i] é um byte, e s[i:j] é uma substring por posições em bytes:

ï e é ocupam dois bytes cada, então a string tem 12 bytes e 10 caracteres. Fatiar por bytes é seguro desde que as posições venham de strings.Index ou funções parecidas, que devolvem offsets em bytes nas fronteiras entre caracteres. Para pegar "os n primeiros caracteres", converta antes para []rune. A página de runes e bytes explica o UTF-8 a fundo.

Strings são imutáveis

Você não pode alterar um byte no lugar: s[0] = 'H' é erro de compilação (cannot assign to s[0] (neither addressable nor a map index expression)). Toda função de strings devolve uma string nova. Para editar, converta para []byte ou []rune, altere o slice e converta de volta:

b := []byte("hello")
b[0] = 'H'
s := string(b) // "Hello"

A imutabilidade também explica por que substrings são baratas: s[2:5] compartilha memória com s em vez de copiar. O outro lado é que uma substring pequena de uma string enorme mantém a string enorme inteira viva. Use strings.Clone (Go 1.20) quando for guardar um pedaço curto de uma entrada grande.

Comparando strings

== e != comparam o conteúdo, e <, > comparam byte a byte, o que dá ordem alfabética para ASCII. strings.Compare existe, mas raramente é necessário; slices.Sort em um []string usa <. Para ordenar texto em outros idiomas respeitando as regras locais, use golang.org/x/text/collate.

Convertendo outros tipos

Números viram strings com strconv.Itoa, strconv.FormatFloat ou fmt.Sprintf, e strings viram números com strconv.Atoi e strconv.ParseFloat. Não escreva string(42): isso gera o caractere com code point 42, "*". A página de conversão de tipos tem a tabela completa.

Perguntas frequentes

Como dividir uma string em Go?

Use strings.Split(s, sep): strings.Split("a,b,c", ",") devolve ["a" "b" "c"]. Para dividir em qualquer sequência de espaços em branco e descartar partes vazias, use strings.Fields(s). strings.SplitN limita o número de partes, e strings.Cut divide uma vez só, em volta do primeiro separador.

Como escrever uma string de várias linhas em Go?

Use uma raw string entre crases:

query := `SELECT id, name
FROM users
WHERE active = true`

Tudo entre as crases é tomado ao pé da letra, incluindo quebras de linha e barras invertidas. Uma raw string não pode conter uma crase.

Como verificar se uma string contém uma substring em Go?

strings.Contains(s, substr) devolve um bool. Funções relacionadas: strings.HasPrefix, strings.HasSuffix, strings.Index (posição ou -1), strings.ContainsAny (qualquer caractere de um conjunto) e strings.EqualFold para igualdade sem diferenciar maiúsculas e minúsculas.

Qual o jeito mais rápido de concatenar strings em Go?

Para poucas strings, + resolve. Quando for montar uma string dentro de um laço, use strings.Builder: chame WriteString várias vezes e String() uma vez no final. += repetido em um laço copia a string inteira a cada vez, então fica lento conforme a string cresce. Para juntar um slice com separador, use strings.Join.

Por que len devolve o tamanho errado da minha string?

len(s) devolve o número de bytes, não de caracteres. Strings em Go são UTF-8, em que caracteres fora do ASCII ocupam de 2 a 4 bytes, então len("héllo") é 6. Use utf8.RuneCountInString(s) para obter o número de code points Unicode.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR