5. Trabalhando com Texto Usando Strings
Texto está em todo lugar na programação. Desde exibir mensagens para usuários, até processar arquivos de dados, passando por construir aplicações web, trabalhar com texto é uma das habilidades mais fundamentais que você vai desenvolver como programador. Em Python, trabalhamos com texto usando strings — sequências de caracteres que podem representar palavras, frases ou qualquer tipo de dado textual.
Você já encontrou strings brevemente em capítulos anteriores ao usar print() e input(). Agora vamos explorar strings em profundidade, aprendendo como criá-las, manipulá-las e usar os poderosos recursos de strings embutidos do Python para resolver problemas reais de processamento de texto.
Neste capítulo, você vai aprender como criar strings com caracteres especiais, combinar strings, extrair partes específicas de strings, mudar seu caso e formatação, buscar texto dentro de strings e entender por que strings se comportam de forma diferente de números quando se trata de modificação. Ao final, você terá uma base sólida para trabalhar com texto em Python.
5.1) Literais de String e Sequências de Escape
5.1.1) Criando Literais de String
Um literal de string é um valor de string escrito diretamente no seu código. Você já viu strings criadas com aspas simples (') ou aspas duplas ("):
# string_basics.py
greeting = 'Hello, World!'
message = "Python is great!"
print(greeting) # Output: Hello, World!
print(message) # Output: Python is great!Aspas simples e aspas duplas funcionam de forma idêntica em Python — a escolha é sua. Porém, ter ambas as opções é útil quando sua string contém caracteres de aspas:
# quotes_in_strings.py
# Usando aspas duplas quando a string contém uma aspa simples
sentence = "It's a beautiful day!"
print(sentence) # Output: It's a beautiful day!
# Usando aspas simples quando a string contém aspas duplas
quote = 'She said, "Hello!"'
print(quote) # Output: She said, "Hello!"Se você precisar incluir o mesmo tipo de aspa que envolve sua string, pode escapá-la com uma barra invertida (\):
# escaping_quotes.py
# Escapando uma aspa simples dentro de uma string com aspas simples
sentence = 'It\'s a beautiful day!'
print(sentence) # Output: It's a beautiful day!
# Escapando aspas duplas dentro de uma string com aspas duplas
quote = "She said, \"Hello!\""
print(quote) # Output: She said, "Hello!"A barra invertida diz ao Python que a aspa seguinte faz parte do conteúdo da string, e não o fim da string.
5.1.2) Strings Multilinha com Aspas Triplas
Para strings que se estendem por múltiplas linhas, Python fornece aspas triplas — ou três aspas simples (''') ou três aspas duplas ("""):
# multiline_strings.py
poem = """Roses are red,
Violets are blue,
Python is awesome,
And so are you!"""
print(poem)
# Output:
# Roses are red,
# Violets are blue,
# Python is awesome,
# And so are you!Strings com aspas triplas preservam todas as quebras de linha e espaçamento exatamente como você digita. Elas são particularmente úteis para blocos de texto mais longos, strings de documentação (que veremos no Capítulo 19), ou quando você precisa incluir tanto aspas simples quanto duplas sem escapar:
# triple_quotes_convenience.py
dialogue = '''The teacher said, "Don't forget: it's important to practice!"'''
print(dialogue) # Output: The teacher said, "Don't forget: it's important to practice!"5.1.3) Sequências de Escape Comuns
Além de escapar aspas, a barra invertida introduz sequências de escape — combinações especiais de dois caracteres que representam caracteres que são difíceis ou impossíveis de digitar diretamente:
# escape_sequences.py
# Nova linha: vai para a próxima linha
print("First line\nSecond line")
# Output:
# First line
# Second line
# Tab: insere espaçamento horizontal
print("Name:\tJohn\nAge:\t25")
# Output:
# Name: John
# Age: 25
# Barra invertida: para incluir uma barra invertida literal
path = "C:\\Users\\Documents"
print(path) # Output: C:\Users\DocumentsAqui estão as sequências de escape mais usadas:
| Escape Sequence | Significado | Exemplo de Saída |
|---|---|---|
\n | Nova linha (quebra de linha) | Duas linhas |
\t | Tab (espaçamento horizontal) | Texto indentado |
\\ | Barra invertida | caractere \ |
\' | Aspa simples | caractere ' |
\" | Aspas duplas | caractere " |
Entender sequências de escape é crucial ao trabalhar com caminhos de arquivos (especialmente no Windows, que usa barras invertidas), saída formatada ou qualquer texto que precise de formatação especial.
5.1.4) Strings Brutas para Barras Invertidas Literais
Às vezes você quer que barras invertidas sejam tratadas literalmente, sem disparar sequências de escape. Isso é comum ao trabalhar com caminhos de arquivos ou expressões regulares (que veremos brevemente no Capítulo 39). Python fornece strings brutas ao prefixar a string com r:
# raw_strings.py
# String normal: barras invertidas disparam sequências de escape
regular = "C:\new\test"
print(regular) # Output: C:
# ew est
# (\n vira nova linha, \t vira tab)
# String bruta: barras invertidas são literais
raw = r"C:\new\test"
print(raw) # Output: C:\new\testEm uma string bruta, \n é literalmente os dois caracteres barra invertida e n, não uma nova linha. Strings brutas são particularmente úteis para caminhos de arquivos no Windows:
# windows_paths.py
# Sem string bruta, você precisa escapar cada barra invertida
path1 = "C:\\Users\\John\\Documents\\file.txt"
# Com string bruta, as barras invertidas funcionam naturalmente
path2 = r"C:\Users\John\Documents\file.txt"
print(path1) # Output: C:\Users\John\Documents\file.txt
print(path2) # Output: C:\Users\John\Documents\file.txtAmbas as abordagens produzem o mesmo resultado, mas strings brutas são mais legíveis quando você tem muitas barras invertidas.
5.2) Concatenação e Repetição de Strings
5.2.1) Concatenando Strings com +
Você pode combinar strings usando o operador +, que é chamado de concatenação:
# string_concatenation.py
first_name = "John"
last_name = "Smith"
# Combinando strings com +
full_name = first_name + " " + last_name
print(full_name) # Output: John Smith
# Construindo strings mais longas
greeting = "Hello, " + full_name + "!"
print(greeting) # Output: Hello, John Smith!A concatenação cria uma nova string colocando as strings uma após a outra. Note que o Python não adiciona espaços automaticamente — você precisa incluí-los explicitamente:
# concatenation_spacing.py
word1 = "Hello"
word2 = "World"
# Sem espaço
no_space = word1 + word2
print(no_space) # Output: HelloWorld
# Com espaço
with_space = word1 + " " + word2
print(with_space) # Output: Hello WorldVocê pode concatenar quantas strings quiser em uma única expressão:
# multiple_concatenation.py
address = "123" + " " + "Main" + " " + "Street"
print(address) # Output: 123 Main StreetLimitação importante: você só pode concatenar strings com outras strings. Tentar concatenar uma string com um número causará um erro:
# concatenation_error.py
age = 25
# Isso vai causar um erro:
# message = "I am " + age + " years old" # TypeError!
# Você deve converter o número para string primeiro
message = "I am " + str(age) + " years old"
print(message) # Output: I am 25 years oldVamos explorar conversão entre string e número em mais detalhes na Seção 5.6.
5.2.2) Repetindo Strings com *
Python fornece uma forma conveniente de repetir uma string várias vezes usando o operador *:
# string_repetition.py
separator = "-" * 20
print(separator) # Output: --------------------
# Criando padrões
pattern = "abc" * 3
print(pattern) # Output: abcabcabc
# Útil para formatar saída
print("=" * 30)
print("Important Message")
print("=" * 30)
# Output:
# ==============================
# Important Message
# ==============================O operador de repetição funciona com qualquer inteiro positivo:
# repetition_examples.py
# Repetir zero vezes gera uma string vazia
nothing = "Hello" * 0
print(nothing) # Output: (empty string)
print(len(nothing)) # Output: 0
# Repetir uma vez devolve a string original
once = "Hello" * 1
print(once) # Output: Hello
# Repetições maiores
many = "Go! " * 5
print(many) # Output: Go! Go! Go! Go! Go!A repetição de strings é particularmente útil para criar separadores visuais, preenchimento (padding) ou gerar dados de teste:
# practical_repetition.py
# Criando uma caixa de texto simples
width = 40
border = "=" * width
title = "Welcome"
padding = " " * ((width - len(title)) // 2)
print(border)
print(padding + title)
print(border)
# Output:
# ========================================
# Welcome
# ========================================5.2.3) Combinando Concatenação e Repetição
Você pode combinar ambos os operadores na mesma expressão, seguindo as regras de precedência de operadores do Python (multiplicação antes de adição, assim como com números):
# combined_operations.py
# A repetição acontece primeiro, depois a concatenação
result = "=" * 10 + " Title " + "=" * 10
print(result) # Output: ========== Title ==========
# Usando parênteses para controlar a ordem
repeated_phrase = ("Hello " + "World ") * 3
print(repeated_phrase) # Output: Hello World Hello World Hello WorldEssas operações formam a base da manipulação de strings, permitindo que você construa strings complexas a partir de partes simples.
5.3) Indexação e Fatiamento de Strings
Strings em Python são sequências de caracteres, o que significa que cada caractere tem uma posição específica. Você pode acessar caracteres individuais ou extrair partes de uma string usando indexação e fatiamento.
5.3.1) Entendendo Índices de String
Cada caractere em uma string tem uma posição numérica chamada índice. Python usa indexação baseada em zero, o que significa que o primeiro caractere está no índice 0, o segundo no índice 1 e assim por diante:
# string_indexing.py
text = "Python"
# Acessando caracteres individuais pelo índice
print(text[0]) # Output: P (primeiro caractere)
print(text[1]) # Output: y (segundo caractere)
print(text[5]) # Output: n (sexto caractere)Aqui está uma representação visual de como índices se mapeiam para caracteres:
String: P y t h o n
Index: 0 1 2 3 4 5Python também suporta índices negativos, que contam a partir do final da string. O índice -1 se refere ao último caractere, -2 ao penúltimo, e assim por diante:
# negative_indexing.py
text = "Python"
print(text[-1]) # Output: n (último caractere)
print(text[-2]) # Output: o (penúltimo)
print(text[-6]) # Output: P (primeiro caractere)Índices negativos são particularmente úteis quando você quer acessar caracteres perto do final de uma string sem saber seu comprimento exato:
String: P y t h o n
Positive: 0 1 2 3 4 5
Negative: -6 -5 -4 -3 -2 -1Importante: Tentar acessar um índice que não existe causará um IndexError:
# index_error.py
text = "Python"
# Isso funciona bem
print(text[5]) # Output: n
# Isso causa um erro porque o índice 6 não existe
# print(text[6]) # IndexError: string index out of range5.3.2) Fatiando Strings para Extrair Substrings
Enquanto a indexação te dá um único caractere, o fatiamento permite extrair uma parte de uma string (chamada de substring). A sintaxe básica é:
string[start:stop]Isso extrai caracteres do índice start até (mas não incluindo) o índice stop:
# basic_slicing.py
text = "Python Programming"
# Extrai caracteres do índice 0 até (mas não incluindo) 6
print(text[0:6]) # Output: Python
# Extrai caracteres do índice 7 até 18
print(text[7:18]) # Output: Programming
# Extrai uma parte do meio
print(text[7:11]) # Output: ProgA coisa mais importante a lembrar é que o índice stop não é incluído no resultado. Pense nos índices como apontando entre os caracteres:
P y t h o n
0 1 2 3 4 5 6Então text[0:6] significa "comece na posição 0 e pare antes da posição 6", dando os caracteres nas posições 0, 1, 2, 3, 4 e 5.
5.3.3) Omitindo Índices de Início ou Fim
Você pode omitir o índice start para fatiar desde o início, ou omitir o índice stop para fatiar até o final:
# omitting_indices.py
text = "Python Programming"
# Do início até o índice 6
print(text[:6]) # Output: Python
# Do índice 7 até o final
print(text[7:]) # Output: Programming
# A string inteira (do início ao fim)
print(text[:]) # Output: Python ProgrammingEsses atalhos são muito comuns em código Python porque deixam as intenções claras e evitam fixar comprimentos no código.
5.3.4) Usando Índices Negativos em Fatias
Índices negativos funcionam em fatias também, permitindo contar a partir do final:
# negative_slice_indices.py
text = "Python Programming"
# Últimos 11 caracteres
print(text[-11:]) # Output: Programming
# Tudo exceto os últimos 11 caracteres
print(text[:-11]) # Output: Python
# Últimos 7 caracteres
print(text[-7:]) # Output: ramming
# Do índice 7 até o antepenúltimo caractere
print(text[7:-3]) # Output: Programm (para antes de 'ing')Índices negativos são especialmente úteis quando você quer excluir um certo número de caracteres do final:
# removing_suffix.py
filename = "document.txt"
# Pega tudo exceto os últimos 4 caracteres (.txt)
name_without_extension = filename[:-4]
print(name_without_extension) # Output: document5.3.5) Fatiando com um Valor de Passo
Fatias podem incluir um terceiro valor chamado passo, que determina quantos caracteres pular:
string[start:stop:step]# slicing_with_step.py
text = "Python Programming"
# Cada segundo caractere da string inteira
print(text[::2]) # Output: Pto rgamn
# Cada segundo caractere do índice 0 ao 6
print(text[0:6:2]) # Output: Pto
# Cada terceiro caractere
print(text[::3]) # Output: Ph oaiUm truque particularmente útil é usar um passo de -1 para inverter uma string:
# reversing_strings.py
text = "Python"
# Inverte a string inteira
reversed_text = text[::-1]
print(reversed_text) # Output: nohtyP
# Exemplo prático: checando palíndromos
word = "radar"
if word == word[::-1]:
print(f"{word} is a palindrome!") # Output: radar is a palindrome!5.3.6) Fatiar Nunca Causa Erros
Ao contrário da indexação, o fatiamento é bem tolerante. Se você especificar índices fora do intervalo, o Python simplesmente os ajusta:
# safe_slicing.py
text = "Python"
# Todos estes funcionam sem erros
print(text[0:100]) # Output: Python (para no final)
print(text[10:20]) # Output: (empty string - início além do fim)
print(text[-100:3]) # Output: Pyt (início ajustado para 0)Esse comportamento torna o fatiamento seguro mesmo quando você não tem certeza do comprimento exato da string.
5.3.7) Exemplos Práticos de Fatiamento
Aqui estão alguns padrões comuns que você usará com frequência:
# practical_slicing.py
text = "Hello, World!"
# Primeiros 5 caracteres
print(text[:5]) # Output: Hello
# Últimos 6 caracteres
print(text[-6:]) # Output: World!
# Tudo exceto o primeiro e o último caractere
print(text[1:-1]) # Output: ello, World
# Cada segundo caractere
print(text[::2]) # Output: Hlo ol!
# Inverter a string
print(text[::-1]) # Output: !dlroW ,olleHEntender indexação e fatiamento é fundamental para processamento de texto em Python. Essas técnicas vão aparecer repetidamente ao longo da sua jornada de programação.
5.4) Métodos Comuns de String para Caso e Espaços em Branco
Strings em Python vêm com muitos métodos embutidos — funções que estão ligadas a objetos string e realizam operações sobre eles. Nesta seção, vamos explorar métodos para mudar o caso e gerenciar espaços em branco, que são essenciais para limpar e formatar texto.
5.4.1) Entendendo Métodos de String
Um método é chamado usando notação de ponto: string.method_name(). Métodos são funções que pertencem a um tipo específico de objeto. Para strings, Python fornece dezenas de métodos úteis:
# method_basics.py
text = "hello"
# Chamando um método em uma string
result = text.upper()
print(result) # Output: HELLO
# A string original não é alterada (vamos discutir por quê na Seção 5.8)
print(text) # Output: helloMétodos podem ser encadeados porque cada método retorna uma nova string:
# method_chaining.py
text = " hello world "
# Encadear múltiplos métodos
result = text.strip().upper().replace("WORLD", "PYTHON")
print(result) # Output: HELLO PYTHON5.4.2) Métodos de Conversão de Caso
Python fornece vários métodos para mudar o caso de strings:
# case_methods.py
text = "Python Programming"
# Converter para maiúsculas
print(text.upper()) # Output: PYTHON PROGRAMMING
# Converter para minúsculas
print(text.lower()) # Output: python programming
# Capitalizar a primeira letra, minúsculas no resto
print(text.capitalize()) # Output: Python programming
# Case de título: primeira letra de cada palavra em maiúsculo
print(text.title()) # Output: Python ProgrammingEsses métodos são particularmente úteis para padronizar entrada de usuário:
# case_normalization.py
# Simulando entrada de usuário
user_input = "YES"
# Comparação sem diferenciar maiúsculas de minúsculas
if user_input.lower() == "yes":
print("User confirmed!") # Output: User confirmed!
# Outra abordagem usando upper()
command = "start"
if command.upper() == "START":
print("Starting process...") # Output: Starting process...O método title() coloca em maiúscula a primeira letra de cada palavra, o que é útil para formatar nomes e títulos:
# title_case.py
name = "john smith"
print(name.title()) # Output: John Smith
book = "the great gatsby"
print(book.title()) # Output: The Great GatsbyNo entanto, esteja ciente de que title() tem limitações com apóstrofos e casos especiais:
# title_limitations.py
text = "it's a beautiful day"
print(text.title()) # Output: It'S A Beautiful Day (note o S maiúsculo)
# Para um title case mais sofisticado, você pode precisar de lógica personalizadaO método capitalize() só capitaliza o primeiro caractere de toda a string:
# capitalize_examples.py
sentence = "python is great"
print(sentence.capitalize()) # Output: Python is great
# Note: apenas a primeira letra é capitalizada
multi_word = "hello world"
print(multi_word.capitalize()) # Output: Hello world (não Hello World)5.4.3) Métodos de Verificação de Caso
Python também fornece métodos para verificar o caso de strings:
# case_checking.py
text1 = "HELLO"
text2 = "hello"
text3 = "Hello World"
# Verificar se todos os caracteres são maiúsculos
print(text1.isupper()) # Output: True
print(text2.isupper()) # Output: False
# Verificar se todos os caracteres são minúsculos
print(text1.islower()) # Output: False
print(text2.islower()) # Output: True
# Verificar se a string está em case de título
print(text3.istitle()) # Output: True
print(text2.istitle()) # Output: FalseEsses métodos de verificação retornam True ou False (valores Booleanos que vimos no Capítulo 3), tornando-os perfeitos para condições:
# case_checking_conditions.py
password = "SECRET123"
if password.isupper():
print("Password is all uppercase") # Output: Password is all uppercase5.4.4) Métodos de Remoção de Espaços em Branco
Espaço em branco inclui espaços, tabs (\t) e quebras de linha (\n). Python fornece métodos para remover espaços em branco das bordas de strings:
# whitespace_removal.py
text = " Hello, World! "
# Remove espaços em branco das duas extremidades
print(text.strip()) # Output: Hello, World!
# Remove espaços em branco da esquerda (início)
print(text.lstrip()) # Output: Hello, World!
# Remove espaços em branco da direita (fim)
print(text.rstrip()) # Output: Hello, World!O método strip() é extremamente útil para limpar entrada de usuário:
# cleaning_input.py
# Simulando entrada de usuário com espaços extras
user_name = " John Smith "
# Limpar a entrada
clean_name = user_name.strip()
print(f"Welcome, {clean_name}!") # Output: Welcome, John Smith!Esses métodos também removem tabs e quebras de linha:
# strip_all_whitespace.py
text = "\n\t Hello \t\n"
print(repr(text)) # Output: '\n\t Hello \t\n'
cleaned = text.strip()
print(repr(cleaned)) # Output: 'Hello'Note que strip(), lstrip() e rstrip() só removem espaços em branco das bordas, não do meio:
# strip_edges_only.py
text = " Hello World "
print(text.strip()) # Output: Hello World (os espaços no meio permanecem)5.4.5) Removendo Caracteres Específicos
Os métodos de strip também podem remover caracteres específicos (não apenas espaços em branco) das bordas:
# Remove vários caracteres diferentes
text = "...Hello!!!"
cleaned = text.strip(".!")
print(cleaned) # Output: HelloQuando você passa uma string para strip(), ele remove qualquer combinação desses caracteres das bordas:
# strip_character_set.py
text = "xxxyyyHelloyyyxxx"
# Remove qualquer x ou y das duas extremidades
result = text.strip("xy")
print(result) # Output: Hello5.4.6) Exemplos Práticos Combinando Métodos de Caso e Espaços em Branco
Aqui estão cenários reais onde esses métodos são inestimáveis:
# practical_text_cleaning.py
# Limpando e padronizando entrada de usuário
user_email = " JohnSmith@EXAMPLE.com "
clean_email = user_email.strip().lower()
print(clean_email) # Output: johnsmith@example.com
# Formatando nomes corretamente
raw_name = " john smith "
formatted_name = raw_name.strip().title()
print(formatted_name) # Output: John Smith
# Processando comandos (sem diferenciar maiúsculas de minúsculas)
command = " START "
if command.strip().upper() == "START":
print("Command recognized!") # Output: Command recognized!Esses métodos formam a base da limpeza e normalização de texto, que você usará constantemente ao processar entrada de usuário, ler arquivos ou preparar dados para análise.
5.5) Buscando e Substituindo em Strings
Encontrar e modificar texto dentro de strings é uma tarefa comum em programação. Python fornece métodos poderosos para buscar substrings e substituir texto.
5.5.1) Encontrando Substrings com find() e index()
O método find() busca uma substring e retorna o índice onde ela aparece pela primeira vez:
# find_method.py
text = "Python is great. Python is powerful."
# Encontrar a primeira ocorrência de "Python"
position = text.find("Python")
print(position) # Output: 0 (encontrado no início)
# Encontrar "great"
position = text.find("great")
print(position) # Output: 10
# Procurar algo que não existe
position = text.find("Java")
print(position) # Output: -1 (not found)O método find() retorna -1 se a substring não for encontrada, o que o torna seguro de usar sem causar erros:
# safe_searching.py
text = "Hello, World!"
# Verificar se uma substring existe
if text.find("World") != -1:
print("Found 'World'!") # Output: Found 'World'!
if text.find("Python") == -1:
print("'Python' not found") # Output: 'Python' not foundVocê também pode buscar uma substring a partir de uma posição específica:
# find_with_start.py
text = "Python is great. Python is powerful."
# Encontrar a primeira ocorrência
first = text.find("Python")
print(first) # Output: 0
# Encontrar a próxima ocorrência após a primeira
second = text.find("Python", first + 1)
print(second) # Output: 17O método index() funciona de forma similar a find(), mas gera um erro se a substring não for encontrada:
# index_method.py
text = "Hello, World!"
# Isso funciona bem
position = text.index("World")
print(position) # Output: 7
# Isto causaria um ValueError:
# position = text.index("Python") # ValueError: substring not foundQuando usar qual:
- Use
find()quando quiser verificar se algo existe (retorna -1 se não encontrar) - Use
index()quando você espera que a substring esteja lá (gera erro se não encontrar)
# choosing_find_vs_index.py
text = "Python Programming"
# Usando find() para verificação segura
if text.find("Java") != -1:
print("Found Java")
else:
print("Java not found") # Output: Java not found
# Usando index() quando você tem certeza de que existe
position = text.index("Python") # Sabemos que Python está lá
print(f"Found at position {position}") # Output: Found at position 05.5.2) Buscando a Partir do Final com rfind() e rindex()
Os métodos rfind() e rindex() buscam a partir da direita (final) da string:
# rfind_method.py
text = "Python is great. Python is powerful."
# Encontrar a última ocorrência de "Python"
last_position = text.rfind("Python")
print(last_position) # Output: 17
# Comparar com find(), que dá a primeira ocorrência
first_position = text.find("Python")
print(first_position) # Output: 0Isso é útil quando você quer a última ocorrência de algo:
# last_occurrence.py
filename = "document.backup.txt"
# Encontrar o último ponto (para obter a extensão do arquivo)
last_dot = filename.rfind(".")
if last_dot != -1:
extension = filename[last_dot:]
print(extension) # Output: .txt5.5.3) Contando Ocorrências com count()
O método count() informa quantas vezes uma substring aparece:
# count_method.py
text = "Python is great. Python is powerful. Python is fun."
# Contar quantas vezes "Python" aparece
count = text.count("Python")
print(count) # Output: 3
# Contar um caractere
letter_count = text.count("o")
print(f"Letter 'o' appears {letter_count} times") # Output: Letter 'o' appears 4 timesVocê também pode contar dentro de um intervalo específico:
# count_in_range.py
text = "abcabcabc"
# Contar "abc" na string inteira
total = text.count("abc")
print(total) # Output: 3
# Contar "abc" apenas nos primeiros 6 caracteres
partial = text.count("abc", 0, 6)
print(partial) # Output: 25.5.4) Substituindo Texto com replace()
O método replace() cria uma nova string com todas as ocorrências de uma substring substituídas:
# replace_method.py
text = "I love Java. Java is great."
# Substituir todas as ocorrências de "Java" por "Python"
new_text = text.replace("Java", "Python")
print(new_text) # Output: I love Python. Python is great.
# A string original permanece inalterada
print(text) # Output: I love Java. Java is great.Você pode limitar o número de substituições com um terceiro argumento:
# limited_replace.py
text = "one one one one"
# Substituir apenas as 2 primeiras ocorrências
result = text.replace("one", "two", 2)
print(result) # Output: two two one oneO método replace() diferencia maiúsculas de minúsculas:
# case_sensitive_replace.py
text = "Python is great. python is powerful."
# Isso só substitui "Python" (P maiúsculo)
result = text.replace("Python", "Java")
print(result) # Output: Java is great. python is powerful.Para substituição sem diferenciar maiúsculas de minúsculas, você precisa tratar manualmente:
# case_insensitive_approach.py
text = "Python is great. python is powerful."
# Converter para minúsculas, substituir, mas isso perde o caso original
result = text.lower().replace("python", "java")
print(result) # Output: java is great. java is powerful.5.5.5) Exemplos Práticos de Busca e Substituição
Aqui estão cenários reais em que esses métodos brilham:
# practical_search_replace.py
# Limpando dados: removendo caracteres indesejados
phone = "123-456-7890"
clean_phone = phone.replace("-", "")
print(clean_phone) # Output: 1234567890
# Censurando palavras
message = "This is a bad word and another bad word."
censored = message.replace("bad", "***")
print(censored) # Output: This is a *** word and another *** word.
# Extraindo extensão de arquivo
filename = "document.txt"
dot_position = filename.rfind(".")
if dot_position != -1:
extension = filename[dot_position + 1:]
print(f"File type: {extension}") # Output: File type: txt
# Contando ocorrências de palavras (abordagem simples)
text = "Python is fun. I love Python. Python rocks!"
word = "Python"
occurrences = text.count(word)
print(f"'{word}' appears {occurrences} times") # Output: 'Python' appears 3 timesEsses métodos de busca e substituição são ferramentas fundamentais para processamento de texto, limpeza de dados e manipulação de strings em programas Python.
5.6) Convertendo Entre Strings e Números
Uma das tarefas mais comuns em programação é converter entre representações textuais e numéricas. Quando você lê entrada de usuário com input(), você obtém uma string — mesmo que o usuário digite um número. Da mesma forma, quando você quer exibir números em texto, precisa convertê-los para strings.
5.6.1) Convertendo Strings para Números
Nós já vimos as funções int() e float() no Capítulo 3, mas vamos explorá-las com mais detalhes:
# string_to_number.py
# Convertendo string para inteiro
age_text = "25"
age = int(age_text)
print(age) # Output: 25
print(type(age)) # Output: <class 'int'>
# Convertendo string para float
price_text = "19.99"
price = float(price_text)
print(price) # Output: 19.99
print(type(price)) # Output: <class 'float'>Essas conversões são essenciais ao processar entrada de usuário:
# user_input_conversion.py
# Simulando entrada de usuário (em código real, você usaria input())
user_age = "30"
user_height = "5.9"
# Converter para números para podermos fazer contas
age = int(user_age)
height = float(user_height)
# Agora podemos fazer cálculos
print(f"In 10 years, you'll be {age + 10}") # Output: In 10 years, you'll be 40
print(f"Your height in meters: {height * 0.3048:.2f}") # Output: Your height in meters: 1.80Importante: A string deve representar um número válido, ou você terá um erro:
# conversion_errors.py
# Estes funcionam bem
print(int("123")) # Output: 123
print(float("3.14")) # Output: 3.14
# Estes causam ValueError:
# print(int("hello")) # ValueError: invalid literal for int()
# print(int("12.5")) # ValueError: invalid literal for int() with base 10
# print(float("12.5.3")) # ValueError: could not convert string to floatVamos aprender a tratar esses erros graciosamente no Capítulo 28. Por enquanto, esteja ciente de que a conversão pode falhar se a string não representar um número válido.
5.6.2) Lidando com Espaços em Branco em Strings Numéricas
As funções de conversão do Python tratam automaticamente espaços em branco no início e no fim:
# whitespace_handling.py
# Todos estes funcionam bem apesar dos espaços
print(int(" 42 ")) # Output: 42
print(float(" 3.14 ")) # Output: 3.14
# Combinando strip() com conversão por segurança
user_input = " 100 "
number = int(user_input.strip())
print(number) # Output: 100Isso é útil ao processar entrada de usuário, que frequentemente contém espaços extras.
5.6.3) Convertendo Números para Strings
A função str() converte qualquer valor para sua representação em string:
# number_to_string.py
age = 25
height = 5.9
# Converter números para strings
age_text = str(age)
height_text = str(height)
print(type(age_text)) # Output: <class 'str'>
print(type(height_text)) # Output: <class 'str'>
# Agora podemos concatená-los com outras strings
message = "I am " + str(age) + " years old"
print(message) # Output: I am 25 years oldIsso é necessário sempre que você quiser combinar números com strings:
# concatenation_with_numbers.py
score = 95
total = 100
# É preciso converter números para strings para concatenar
result = "Score: " + str(score) + "/" + str(total)
print(result) # Output: Score: 95/100
# Alternativa: usar f-strings (detalhado no Capítulo 6)
result = f"Score: {score}/{total}"
print(result) # Output: Score: 95/1005.6.4) Convertendo Entre int e float
Você também pode converter entre tipos inteiro e float:
# int_float_conversion.py
# Float para int (trunca a parte decimal)
price = 19.99
price_int = int(price)
print(price_int) # Output: 19 (parte decimal removida, não arredondada)
# Int para float
age = 25
age_float = float(age)
print(age_float) # Output: 25.0Importante: Converter float para int trunca (corta) a parte decimal — não arredonda:
# truncation_not_rounding.py
print(int(3.9)) # Output: 3 (não 4!)
print(int(3.1)) # Output: 3
print(int(-3.9)) # Output: -3 (trunca em direção a zero)
# Para arredondar, use a função round() antes (vista no Capítulo 4)
print(int(round(3.9))) # Output: 45.6.5) Exemplos Práticos de Conversão
Aqui estão cenários reais em que conversão de tipo é essencial:
# practical_conversions.py
# Lendo e processando entrada de usuário
# (Simulando input() - em código real, você usaria input())
user_input = "42"
# Converter para número para fazer cálculos
number = int(user_input)
doubled = number * 2
print(f"Double of {number} is {doubled}") # Output: Double of 42 is 84
# Construindo saída formatada
name = "John"
age = 30
height = 5.9
# Método 1: Converter números para strings
info = name + " is " + str(age) + " years old and " + str(height) + " feet tall"
print(info) # Output: John is 30 years old and 5.9 feet tall
# Método 2: Usar f-strings (mais legível - visto no Capítulo 6)
info = f"{name} is {age} years old and {height} feet tall"
print(info) # Output: John is 30 years old and 5.9 feet tall
# Processando dados de arquivos (prévia)
data_line = "100,200,300" # Simulando uma linha de um arquivo CSV
numbers = data_line.split(",") # Divide em lista de strings
total = int(numbers[0]) + int(numbers[1]) + int(numbers[2])
print(f"Total: {total}") # Output: Total: 6005.6.6) Armadilhas Comuns de Conversão
Fique atento a estes erros comuns:
# conversion_pitfalls.py
# Armadilha 1: Tentar converter strings não numéricas
# text = "hello"
# number = int(text) # ValueError!
# Armadilha 2: Esquecer de converter antes de fazer contas
age_text = "25"
# next_year = age_text + 1 # TypeError: can only concatenate str to str
# Abordagem correta:
age = int(age_text)
next_year = age + 1
print(next_year) # Output: 26
# Armadilha 3: Perder precisão com int()
price = 19.99
price_int = int(price) # Vira 19, não 20!
print(price_int) # Output: 19
# Armadilha 4: Tentar converter strings com vírgulas ou símbolos de moeda
# price_text = "$1,234.56"
# price = float(price_text) # ValueError!
# Você precisaria limpar a string primeiro:
price_text = "$1,234.56"
clean_price = price_text.replace("$", "").replace(",", "")
price = float(clean_price)
print(price) # Output: 1234.56Entender conversão de tipos é crucial para construir programas que interajam com usuários e processem dados do mundo real. Você usará essas conversões constantemente ao longo da sua jornada com Python.
5.7) Verificando Substrings com in e not in
Python fornece formas simples e legíveis de verificar se uma string contém outra usando os operadores in e not in. Eles são extremamente úteis para validação, filtragem e tomada de decisões em seus programas.
5.7.1) Usando in para Verificar Substrings
O operador in retorna True se uma string for encontrada dentro de outra, e False caso contrário:
# in_operator.py
text = "Python is a powerful programming language"
# Verificar se a substring existe
print("Python" in text) # Output: True
print("powerful" in text) # Output: True
print("Java" in text) # Output: FalseIsso é muito mais legível do que usar find() ou index():
# in_vs_find.py
text = "Hello, World!"
# Usando in (claro e legível)
if "World" in text:
print("Found World!") # Output: Found World!
# Usando find (menos legível)
if text.find("World") != -1:
print("Found World!") # Output: Found World!O operador in diferencia maiúsculas de minúsculas:
# case_sensitivity.py
text = "Python Programming"
print("python" in text) # Output: False (p minúsculo)
print("Python" in text) # Output: True (P maiúsculo)
# Para verificação sem diferenciar maiúsculas de minúsculas, converta para minúsculas antes
print("python" in text.lower()) # Output: True5.7.2) Usando not in para Verificar Ausência
O operador not in verifica se uma substring NÃO está presente:
# not_in_operator.py
text = "Python is great"
print("Java" not in text) # Output: True (Java não está lá)
print("Python" not in text) # Output: False (Python está lá)Isso é particularmente útil para validação:
# validation_examples.py
# Verificando caracteres inválidos em um nome de usuário
username = "john_smith"
if " " not in username:
print("Username is valid (no spaces)") # Output: Username is valid (no spaces)5.7.3) Métodos Adicionais de Verificação de Strings
Python fornece vários outros métodos úteis para verificar propriedades de strings:
# string_checking_methods.py
text = "Python"
# Verificar se a string começa com uma substring
print(text.startswith("Py")) # Output: True
print(text.startswith("Ja")) # Output: False
# Verificar se a string termina com uma substring
print(text.endswith("on")) # Output: True
print(text.endswith("ing")) # Output: False
# Estes são mais precisos do que usar in
filename = "report.txt"
print(filename.endswith(".txt")) # Output: True
print(".txt" in filename) # Output: True (mas menos preciso)
# startswith/endswith podem verificar múltiplas opções
filename = "document.pdf"
print(filename.endswith((".pdf", ".doc", ".txt"))) # Output: TrueEsses métodos de verificação são ferramentas essenciais para validação de entrada, filtragem de dados e lógica condicional em seus programas. Eles tornam o código mais legível e fácil de manter do que buscas manuais em strings.
5.8) Strings São Imutáveis: O Que Isso Significa na Prática
Uma das características mais importantes das strings em Python é que elas são imutáveis — uma vez criadas, não podem ser alteradas. Isso pode parecer uma limitação no começo, mas entender a imutabilidade é crucial para escrever código Python correto e evitar bugs sutis.
5.8.1) O Que Imutabilidade Significa
Quando dizemos que strings são imutáveis, queremos dizer que você não pode modificar os caracteres de uma string existente. Qualquer operação que pareça "mudar" uma string na verdade cria uma nova string:
# immutability_basics.py
text = "Hello"
# Isso parece mudar a string, mas não muda
text = text + " World"
print(text) # Output: Hello World
# O que realmente aconteceu:
# 1. Python criou uma nova string "Hello World"
# 2. A variável 'text' agora se refere a essa nova string
# 3. A string original "Hello" ainda existe (até ser coletada pelo garbage collector)Você não pode mudar caracteres individuais de uma string:
# cannot_modify_characters.py
text = "Hello"
# Isso causa um erro:
# text[0] = "J" # TypeError: 'str' object does not support item assignment
# Você deve criar uma nova string em vez disso
text = "J" + text[1:]
print(text) # Output: JelloIsso é fundamentalmente diferente de como listas funcionam (que veremos no Capítulo 13). Listas são mutáveis — você pode mudar seus elementos:
# lists_are_mutable.py
# Prévia de listas (tratadas no Capítulo 13)
numbers = [1, 2, 3]
numbers[0] = 10 # Isso funciona bem com listas
print(numbers) # Output: [10, 2, 3]
# Mas strings não permitem isso:
text = "Hello"
# text[0] = "J" # TypeError com strings!5.8.2) Por Que Métodos de String Retornam Novas Strings
Todos os métodos de string que parecem modificar uma string na verdade retornam uma nova string, deixando a original inalterada:
# methods_return_new_strings.py
original = "hello world"
# Esses métodos retornam novas strings
uppercase = original.upper()
capitalized = original.capitalize()
replaced = original.replace("world", "Python")
# A string original permanece inalterada
print(original) # Output: hello world
print(uppercase) # Output: HELLO WORLD
print(capitalized) # Output: Hello world
print(replaced) # Output: hello PythonÉ por isso que você precisa atribuir o resultado a uma variável (ou usar a mesma variável) para manter as alterações:
# keeping_changes.py
text = " hello "
# Errado: o resultado é perdido
text.strip()
print(text) # Output: hello (ainda com espaços!)
# Correto: atribuir o resultado
text = text.strip()
print(text) # Output: hello (espaços removidos)Esse é um erro comum para iniciantes:
# common_mistake.py
message = "python programming"
# Erro: chamar o método mas não usar o resultado
message.upper()
message.replace("python", "Python")
print(message) # Output: python programming (inalterado!)
# Correto: atribuir os resultados
message = message.upper()
message = message.replace("PYTHON", "Python")
print(message) # Output: Python PROGRAMMING5.8.3) Implicações da Imutabilidade
Entender a imutabilidade ajuda você a escrever código melhor:
1. Strings são seguras para compartilhar:
# safe_sharing.py
original = "Hello"
copy = original # Ambas as variáveis apontam para a mesma string
# Como strings são imutáveis, isso é seguro
copy = copy + " World"
print(original) # Output: Hello (inalterada)
print(copy) # Output: Hello World (nova string)2. Operações com strings criam novos objetos:
# new_objects.py
text = "Python"
# Cada operação cria um novo objeto string
result1 = text.upper()
result2 = text.lower()
result3 = text.replace("P", "J")
# Todos são objetos diferentes
print(id(text)) # Algum endereço de memória
print(id(result1)) # Endereço de memória diferente
print(id(result2)) # Endereço de memória diferente
print(id(result3)) # Endereço de memória diferente3. Construir strings em loops pode ser ineficiente:
# inefficient_string_building.py
# Isso cria muitos objetos temporários de string
result = ""
for i in range(5):
result = result + str(i) # Cria uma nova string a cada vez
print(result) # Output: 01234
# Abordagem mais eficiente (para muitas concatenações):
# Usar uma lista e join (vamos aprender isso no Capítulo 6)
parts = []
for i in range(5):
parts.append(str(i))
result = "".join(parts)
print(result) # Output: 012345.8.4) Imutabilidade e Argumentos de Função
Quando você passa uma string para uma função, não precisa se preocupar com ela sendo modificada acidentalmente:
# safe_function_arguments.py
def process_text(text):
# Qualquer operação cria novas strings
text = text.upper()
text = text.replace("A", "X")
return text
original = "banana"
result = process_text(original)
print(original) # Output: banana (inalterada)
print(result) # Output: BXNXNX (versão modificada)Isso é diferente de tipos mutáveis (como listas, que veremos no Capítulo 13), onde modificações dentro de funções afetam o objeto original.
5.8.5) Visualizando a Imutabilidade
Aqui está uma representação visual do que acontece quando você "modifica" uma string:
Entender que strings são imutáveis ajuda você a:
- Evitar erros em que esquece de capturar resultados de métodos
- Entender por que operações com strings criam novos objetos
- Escrever código mais eficiente ao construir strings grandes
- Compartilhar strings com segurança entre diferentes partes do seu programa
Essa imutabilidade é uma característica fundamental que distingue strings de tipos mutáveis como listas, que vamos explorar em detalhes na Parte IV deste livro.
Resumo do Capítulo:
Neste capítulo, você aprendeu o básico de como trabalhar com texto em Python usando strings. Agora você entende como:
- Criar literais de string usando aspas e sequências de escape
- Combinar strings com concatenação e repetição
- Acessar caracteres individuais e extrair substrings com indexação e fatiamento
- Transformar strings usando métodos de conversão de caso e remoção de espaços em branco
- Buscar e substituir texto dentro de strings
- Converter entre strings e números para processamento de entrada e formatação de saída
- Verificar substrings usando os operadores
inenot in - Reconhecer que strings são imutáveis e o que isso significa para o seu código
Essas habilidades de manipulação de strings formam a base do processamento de texto em Python. Você usará essas técnicas constantemente ao construir interfaces com o usuário, processar arquivos de dados, validar entrada e formatar saída.
No próximo capítulo, vamos expandir esses fundamentos explorando técnicas mais avançadas de manipulação de strings, incluindo dividir e juntar strings, formatação poderosa com f-strings e o método format(), e entendendo codificação de texto para trabalhar com caracteres internacionais.