🔤 Aula 48 – Tutorial Golang – String Functions – Manipulação de Strings na Prática
Introdução
O pacote strings da biblioteca padrão do Go oferece uma vasta coleção de funções para manipulação de strings. Diferente de linguagens orientadas a objetos onde você chama métodos diretamente no objeto, em Go essas são funções que recebem a string como primeiro argumento.
Nesta aula vamos além do Go by Example — vamos ver cada função com exemplos reais de uso em projetos, como validação de entradas, parsing de dados, construção de URLs e muito mais.
O código completo desta aula está disponível no repositório: github.com/toticavalcanti/learning_golang
1. Exemplo Base (Go by Example)
Antes de mergulhar nos exemplos práticos, veja o exemplo canônico do Go by Example para ter uma visão geral das funções disponíveis:
48 - string-functions/basic/string_functions.go
package mainimport (
"fmt"
s "strings"
)
var p = fmt.Println
func main() {
p("Contains: ", s.Contains("test", "es"))
p("Count: ", s.Count("test", "t"))
p("HasPrefix: ", s.HasPrefix("test", "te"))
p("HasSuffix: ", s.HasSuffix("test", "st"))
p("Index: ", s.Index("test", "e"))
p("Join: ", s.Join([]string{"a", "b"}, "-"))
p("Repeat: ", s.Repeat("a", 5))
p("Replace: ", s.Replace("foo", "o", "0", -1))
p("Replace: ", s.Replace("foo", "o", "0", 1))
p("Split: ", s.Split("a-b-c-d-e", "-"))
p("ToLower: ", s.ToLower("TEST"))
p("ToUpper: ", s.ToUpper("test"))
}
Antes de rodar o código, precisamos preparar o terreno no terminal. Se você tentar executar o arquivo direto, o editor pode travar o autocomplete ou exibir o erro clássico de "missing main module". Isso acontece porque o Go precisa mapear o escopo do projeto para o Language Server (gopls) funcionar corretamente.
Para resolver isso, siga estes três comandos rápidos no seu terminal:
1. Navegar até a pasta raiz do projeto
cd C:\Users\your-profile\my_projects\go\learning_golangO comando cd serve para entrar no diretório principal onde centralizaremos nossos estudos de Go.
2. Inicializar o módulo Go (O mapa do projeto)
go mod init learning_golangEsta é a grande sacada. Esse comando cria o arquivo go.mod na raiz. Ele funciona como a "planta baixa" do seu projeto, dizendo para o compilador e para o IDE exatamente onde o seu workspace começa, destravando as ferramentas de formatação e o autocomplete.
Ao rodar o comando, o Go retornará uma mensagem parecida com esta no terminal:
go: creating new go.mod: module learning_golang
go: to add module requirements and sums:
go mod tidyO que isso significa?
- Linha 1: Confirma que o arquivo
go.modfoi gerado com sucesso sob o nome do módulo que escolhemos. - Linha 2 e 3 (
go mod tidy): É uma recomendação do Go. O comandogo mod tidyserve para sincronizar suas dependências. Ele analisa seu código, baixa as bibliotecas externas que você importou e remove aquelas que você não está mais utilizando. Como neste início estamos usando apenas pacotes nativos da linguagem, não é necessário executá-lo agora.
3. Entrar na pasta do exercício e executar
cd basic
go run string_functions.goAgora sim, entramos na pasta específica do exemplo e rodamos o go run, que compila o código em memória e já exibe o resultado das funções de string direto na tela.
Para rodar:
go run string_functions.goSaída esperada:
Contains: true
Count: 2
HasPrefix: true
HasSuffix: true
Index: 1
Join: a-b
Repeat: aaaaa
Replace: f00
Replace: f0o
Split: [a b c d e]
ToLower: test
ToUpper: TESTAgora vamos ver cada grupo de funções com aplicações reais.
2. Busca e Verificação
Funções como Contains, HasPrefix, HasSuffix e Index são fundamentais para validação de entradas e parsing de dados.
48 - string-functions/busca/busca.go
package mainimport (
"fmt"
"strings"
)
// ValidarEmail faz uma validação simples de email
func ValidarEmail(email string) bool {
return strings.Contains(email, "@") && strings.Contains(email, ".")
}
// ValidarURL verifica se uma URL começa com http ou https
func ValidarURL(url string) bool {
return strings.HasPrefix(url, "http://") || strings.HasPrefix(url, "https://")
}
// ValidarArquivoImagem verifica se o arquivo é uma imagem pelo sufixo
func ValidarArquivoImagem(nomeArquivo string) bool {
extensoes := []string{".jpg", ".jpeg", ".png", ".gif", ".webp"}
nomeLower := strings.ToLower(nomeArquivo)
for _, ext := range extensoes {
if strings.HasSuffix(nomeLower, ext) {
return true
}
}
return false
}
// EncontrarPalavraChave retorna a posição da primeira ocorrência
func EncontrarPalavraChave(texto, palavra string) int {
return strings.Index(strings.ToLower(texto), strings.ToLower(palavra))
}
func main() {
// Validação de email
emails := []string{"usuario@exemplo.com", "invalido", "outro@dominio.org"}
for _, email := range emails {
fmt.Printf("Email %q válido: %v\n", email, ValidarEmail(email))
}
fmt.Println()
// Validação de URL
urls := []string{"https://codigofluente.com.br", "ftp://arquivo.com", "http://api.exemplo.com"}
for _, url := range urls {
fmt.Printf("URL %q válida: %v\n", url, ValidarURL(url))
}
fmt.Println()
// Validação de imagem
arquivos := []string{"foto.jpg", "documento.pdf", "banner.PNG", "script.go"}
for _, arq := range arquivos {
fmt.Printf("Arquivo %q é imagem: %v\n", arq, ValidarArquivoImagem(arq))
}
fmt.Println()
// Busca de palavra-chave
texto := "Aprenda Kubernetes e Docker no Código Fluente gratuitamente"
palavras := []string{"kubernetes", "python", "docker"}
for _, p := range palavras {
pos := EncontrarPalavraChave(texto, p)
if pos >= 0 {
fmt.Printf("Palavra %q encontrada na posição %d\n", p, pos)
} else {
fmt.Printf("Palavra %q não encontrada\n", p)
}
}
}
Para rodar:
go run busca.goSaída esperada:
Email "usuario@exemplo.com" válido: true
Email "invalido" válido: false
Email "outro@dominio.org" válido: true
URL "https://codigofluente.com.br" válida: true
URL "ftp://arquivo.com" válida: false
URL "http://api.exemplo.com" válida: true
Arquivo "foto.jpg" é imagem: true
Arquivo "documento.pdf" é imagem: false
Arquivo "banner.PNG" é imagem: true
Arquivo "script.go" é imagem: false
Palavra "kubernetes" encontrada na posição 8
Palavra "python" não encontrada
Palavra "docker" encontrada na posição 22
3. Transformação de Strings
ToLower, ToUpper, Title, TrimSpace e Trim são essenciais para normalização de dados vindos de usuários ou APIs externas.
48 - string-functions/transformacao/transformacao.go
package main
import (
"fmt"
"strings"
)
// NormalizarNome limpa e formata um nome de usuário
func NormalizarNome(nome string) string {
nome = strings.TrimSpace(nome)
nome = strings.Title(strings.ToLower(nome))
return nome
}
// NormalizarSlug converte um título em slug para URL
func NormalizarSlug(titulo string) string {
slug := strings.ToLower(titulo)
slug = strings.TrimSpace(slug)
// Remove o hífen isolado entre espaços antes de substituir
slug = strings.ReplaceAll(slug, " - ", " ")
slug = strings.ReplaceAll(slug, " ", "-")
return slug
}
// LimparCSV remove aspas e espaços extras de campos CSV
func LimparCSV(campo string) string {
campo = strings.TrimSpace(campo)
campo = strings.Trim(campo, """)
campo = strings.TrimSpace(campo)
return campo
}
func main() {
// Normalização de nomes
nomes := []string{" joão silva ", "MARIA SANTOS", "pedro ALVES"}
for _, nome := range nomes {
fmt.Printf("Original: %q → Normalizado: %q\n", nome, NormalizarNome(nome))
}
fmt.Println()
// Geração de slugs
titulos := []string{
"Aula 15 - Segurança no Kubernetes",
"Como usar Docker em Produção",
"Machine Learning com Python",
}
for _, titulo := range titulos {
fmt.Printf("Título: %q\nSlug: %q\n\n", titulo, NormalizarSlug(titulo))
}
// Limpeza de CSV
campos := []string{`" João Silva "`, `" Engenheiro "`, `" São Paulo "`}
fmt.Println("Campos CSV limpos:")
for _, campo := range campos {
fmt.Printf(" %q → %q\n", campo, LimparCSV(campo))
}
}
Para rodar:
go run transformacao.goSaída esperada:
Original: " joão silva " → Normalizado: "João Silva"
Original: "MARIA SANTOS" → Normalizado: "Maria Santos"
Original: "pedro ALVES" → Normalizado: "Pedro Alves"
Título: "Aula 15 - Segurança no Kubernetes"
Slug: "aula-15-segurança-no-kubernetes"
Título: "Como usar Docker em Produção"
Slug: "como-usar-docker-em-produção"
Título: "Machine Learning com Python"
Slug: "machine-learning-com-python"
Campos CSV limpos:
"" João Silva "" → "João Silva"
"" Engenheiro "" → "Engenheiro"
"" São Paulo "" → "São Paulo"
4. Split e Join
Split e Join são fundamentais para parsing de dados estruturados como CSV, listas de tags, query strings e muito mais.
48 - string-functions/split-join/split_join.go
package main
import (
"fmt"
"strings"
)
// ParsearTags converte uma string de tags em slice
func ParsearTags(tags string) []string {
partes := strings.Split(tags, ",")
resultado := make([]string, 0, len(partes))
for _, tag := range partes {
tag = strings.TrimSpace(tag)
tag = strings.ToLower(tag)
if tag != "" {
resultado = append(resultado, tag)
}
}
return resultado
}
// ParsearQueryString extrai parâmetros de uma query string simples
func ParsearQueryString(query string) map[string]string {
params := make(map[string]string)
pares := strings.Split(query, "&")
for _, par := range pares {
partes := strings.SplitN(par, "=", 2)
if len(partes) == 2 {
params[partes[0]] = partes[1]
}
}
return params
}
// ConstruirCSV converte um slice de strings em linha CSV
func ConstruirCSV(campos []string) string {
return strings.Join(campos, ",")
}
// ParsearLinhaCSV divide uma linha CSV em campos
func ParsearLinhaCSV(linha string) []string {
campos := strings.Split(linha, ",")
for i, campo := range campos {
campos[i] = strings.TrimSpace(campo)
}
return campos
}
func main() {
// Parsing de tags
tagStr := "golang, docker, kubernetes, devops, cloud"
tags := ParsearTags(tagStr)
fmt.Printf("Tags originais: %q\n", tagStr)
fmt.Printf("Tags parseadas: %v\n", tags)
fmt.Printf("Total de tags: %d\n\n", len(tags))
// Parsing de query string
query := "page=2&limit=10&search=kubernetes&order=desc"
params := ParsearQueryString(query)
fmt.Printf("Query: %q\n", query)
fmt.Println("Parâmetros:")
for k, v := range params {
fmt.Printf(" %s = %s\n", k, v)
}
fmt.Println()
// Construção e parsing de CSV
dados := [][]string{
{"João Silva", "Engenheiro", "São Paulo"},
{"Maria Santos", "Desenvolvedora", "Rio de Janeiro"},
{"Pedro Alves", "DevOps", "Belo Horizonte"},
}
fmt.Println("Gerando CSV:")
for _, linha := range dados {
csv := ConstruirCSV(linha)
fmt.Println(csv)
}
fmt.Println()
// Parsing de CSV
linhaCSV := "Ana Costa, Product Manager, Curitiba"
campos := ParsearLinhaCSV(linhaCSV)
fmt.Printf("Linha CSV: %q\n", linhaCSV)
fmt.Printf("Nome: %s | Cargo: %s | Cidade: %s\n", campos[0], campos[1], campos[2])
}
Para rodar:
go run split_join.goSaída esperada:
Tags originais: "golang, docker, kubernetes, devops, cloud"
Tags parseadas: [golang docker kubernetes devops cloud]
Total de tags: 5
Query: "page=2&limit=10&search=kubernetes&order=desc"
Parâmetros:
page = 2
limit = 10
search = kubernetes
order = desc
Gerando CSV:
João Silva,Engenheiro,São Paulo
Maria Santos,Desenvolvedora,Rio de Janeiro
Pedro Alves,DevOps,Belo Horizonte
Linha CSV: "Ana Costa, Product Manager, Curitiba"
Nome: Ana Costa | Cargo: Product Manager | Cidade: Curitiba
5. Replace e Count
Replace, ReplaceAll e Count são muito usados para sanitização de dados, templates simples e análise de texto.
48 - string-functions/replace-count/replace_count.go
package main
import (
"fmt"
"strings"
)
// SanitizarHTML remove tags HTML básicas de um texto
func SanitizarHTML(html string) string {
tags := []string{"<p>", "</p>", "<br>", "<br/>", "<strong>", "</strong>",
"<em>", "</em>", "<h1>", "</h1>", "<h2>", "</h2>"}
resultado := html
for _, tag := range tags {
resultado = strings.ReplaceAll(resultado, tag, "")
}
return strings.TrimSpace(resultado)
}
// TemplateSimples substitui variáveis num template
func TemplateSimples(template string, vars map[string]string) string {
resultado := template
for chave, valor := range vars {
resultado = strings.ReplaceAll(resultado, "{{"+chave+"}}", valor)
}
return resultado
}
// AnalisarTexto conta ocorrências de palavras-chave
func AnalisarTexto(texto string, palavras []string) map[string]int {
textoLower := strings.ToLower(texto)
contagem := make(map[string]int)
for _, palavra := range palavras {
contagem[palavra] = strings.Count(textoLower, strings.ToLower(palavra))
}
return contagem
}
func main() {
// Sanitização de HTML
htmlBruto := "<h2><strong>Kubernetes</strong></h2><p>Aprenda <em>K8S</em> do zero.</p>"
fmt.Printf("HTML: %s\n", htmlBruto)
fmt.Printf("Texto: %s\n\n", SanitizarHTML(htmlBruto))
// Template simples
template := "Olá, {{nome}}! Seu curso de {{curso}} começa em {{data}}."
vars := map[string]string{
"nome": "João",
"curso": "Kubernetes",
"data": "01/06/2026",
}
fmt.Printf("Template: %s\n", template)
fmt.Printf("Resultado: %s\n\n", TemplateSimples(template, vars))
// Análise de texto
descricao := `O Código Fluente oferece aulas gratuitas de Kubernetes, Docker e DevOps.
Kubernetes é usado para orquestração de containers Docker em produção.
Aprenda DevOps na prática com projetos reais.`
palavrasChave := []string{"kubernetes", "docker", "devops", "python"}
contagens := AnalisarTexto(descricao, palavrasChave)
fmt.Println("Análise de palavras-chave:")
for palavra, count := range contagens {
fmt.Printf(" %q aparece %d vez(es)\n", palavra, count)
}
}
Para rodar:
go run replace_count.goSaída esperada:
HTML: <h2><strong>Kubernetes</strong></h2><p>Aprenda <em>K8S</em> do zero.</p>
Texto: KubernetesAprenda K8S do zero.
Template: Olá, {{nome}}! Seu curso de {{curso}} começa em {{data}}.
Resultado: Olá, João! Seu curso de Kubernetes começa em 01/06/2026.
Análise de palavras-chave:
"kubernetes" aparece 2 vez(es)
"docker" aparece 2 vez(es)
"devops" aparece 2 vez(es)
"python" aparece 0 vez(es)
6. Repeat e Pad
Repeat é útil para formatação de saídas, geração de separadores e construção de strings estruturadas.
48 - string-functions/repeat/repeat.go
package main
import (
"fmt"
"strings"
)
// ImprimirTabela formata dados em tabela simples no terminal
func ImprimirTabela(headers []string, linhas [][]string) {
largura := 20
separador := strings.Repeat("-", largura*len(headers)+len(headers)+1)
fmt.Println(separador)
for _, h := range headers {
padding := largura - len(h)
fmt.Printf("|%s%s", h, strings.Repeat(" ", padding))
}
fmt.Println("|")
fmt.Println(separador)
for _, linha := range linhas {
for _, campo := range linha {
if len(campo) > largura {
campo = campo[:largura-3] + "..."
}
padding := largura - len(campo)
fmt.Printf("|%s%s", campo, strings.Repeat(" ", padding))
}
fmt.Println("|")
}
fmt.Println(separador)
}
// GerarSenhaVisual gera representação visual de força de senha
func GerarSenhaVisual(forca int) string {
if forca > 10 {
forca = 10
}
preenchido := strings.Repeat("█", forca)
vazio := strings.Repeat("░", 10-forca)
return "[" + preenchido + vazio + "]"
}
func main() {
headers := []string{"Nome", "Cargo", "Cidade"}
linhas := [][]string{
{"João Silva", "Engenheiro Go", "São Paulo"},
{"Maria Santos", "DevOps Engineer", "Rio de Janeiro"},
{"Pedro Alves", "K8S Specialist", "Belo Horizonte"},
}
ImprimirTabela(headers, linhas)
fmt.Println()
senhas := []struct {
senha string
forca int
}{
{"123", 2},
{"senha123", 5},
{"S3nh@F0rt3!", 9},
}
fmt.Println("Força das senhas:")
for _, s := range senhas {
fmt.Printf(" %q %s\n", s.senha, GerarSenhaVisual(s.forca))
}
}
Para rodar:
go run repeat.goSaída esperada:
---------------------------------------------------------------------
|Nome |Cargo |Cidade |
|João Silva |Engenheiro Go |São Paulo |
|Maria Santos |DevOps Engineer |Rio de Janeiro |
|Pedro Alves |K8S Specialist |Belo Horizonte |
Força das senhas:
"123" [██░░░░░░░░]
"senha123" [█████░░░░░]
"S3nh@F0rt3!" [█████████░]
7. strings.Builder — Construção Eficiente
Para concatenar muitas strings em loop, use strings.Builder em vez de +. É muito mais eficiente pois evita alocações desnecessárias de memória.
48 - string-functions/builder/builder.go
package main
import (
"fmt"
"strings"
)
// GerarHTMLLista cria uma lista HTML a partir de um slice
func GerarHTMLLista(itens []string) string {
var sb strings.Builder
sb.WriteString("<ul>\n")
for _, item := range itens {
sb.WriteString(" <li>")
sb.WriteString(item)
sb.WriteString("</li>\n")
}
sb.WriteString("</ul>")
return sb.String()
}
// GerarRelatorio constrói um relatório textual
func GerarRelatorio(titulo string, dados map[string]int) string {
var sb strings.Builder
separador := strings.Repeat("=", 40)
sb.WriteString(separador + "\n")
sb.WriteString(fmt.Sprintf("RELATÓRIO: %s\n", strings.ToUpper(titulo)))
sb.WriteString(separador + "\n\n")
total := 0
for chave, valor := range dados {
sb.WriteString(fmt.Sprintf(" %-20s: %d\n", chave, valor))
total += valor
}
sb.WriteString("\n" + strings.Repeat("-", 40) + "\n")
sb.WriteString(fmt.Sprintf(" %-20s: %d\n", "TOTAL", total))
return sb.String()
}
func main() {
cursos := []string{"Python", "Go", "Kubernetes", "Docker", "Terraform"}
html := GerarHTMLLista(cursos)
fmt.Println("HTML gerado:")
fmt.Println(html)
fmt.Println()
visitasPorCurso := map[string]int{
"Python": 1520,
"Kubernetes": 843,
"Docker": 967,
"Go": 412,
"Django": 731,
}
relatorio := GerarRelatorio("Visitas por Curso", visitasPorCurso)
fmt.Print(relatorio)
}
Para rodar:
go run builder.goSaída esperada:
HTML gerado:
<ul>
<li>Python</li>
<li>Go</li>
<li>Kubernetes</li>
<li>Docker</li>
<li>Terraform</li>
</ul>
========================================
RELATÓRIO: VISITAS POR CURSO
Python : 1520
Kubernetes : 843
Docker : 967
Go : 412
Django : 731
TOTAL : 4473
Conclusão
Nesta aula exploramos as principais funções do pacote strings do Go com exemplos práticos de uso real:
- Busca e verificação —
Contains,HasPrefix,HasSuffix,Indexpara validação de emails, URLs e arquivos - Transformação —
ToLower,ToUpper,TrimSpace,Trimpara normalização de dados - Split e Join — parsing de CSV, query strings e listas de tags
- Replace e Count — sanitização de HTML, templates simples e análise de texto
- Repeat — formatação de saídas e interfaces textuais
- strings.Builder — construção eficiente de strings em loops
O pacote strings é um dos mais usados em Go no dia a dia. Dominar essas funções economiza muito tempo e evita reinventar a roda em situações comuns de manipulação de texto.
O código completo desta aula está disponível no repositório: github.com/toticavalcanti/learning_golang
Na próxima aula, vamos explorar String Formatting em Go — o poderoso pacote fmt com todos os verbos de formatação e suas aplicações práticas.
Até a próxima aula!