Strings em Python - #04
Tags: python, beginners, programming, tutorial
Published: 2022-04-19 14:59:16

{% youtube https://youtu.be/Ab-edjxtbvA %}

## Introdução

_Strings_ representam cadeias ou sequências de caracteres, em outras palavras, texto.

Neste capítulo vamos aprender a utilizar algumas funções pré definidas usadas com as strings, mas antes gostaria de apresentar a função **_input()_** recebendo uma mensagem de texto. 

### Usando o **_input()_** com mensagem

Podemos fornecer uma mensagem ao usuário, como valor na função **_input()_**. Chamamos de **argumento** o valor que fornecemos numa função.

```python
#Sintaxe - input() com argumentos
<variável> = input(<mensagem_tela>)
```

Nosso programa da seção anterior pode ser reescrito com o **_input_** recebendo a mensagem a ser escrita na tela.

```python
#Programa para ler e imprimir nome do usuario
name = input('Digite seu nome:')
print('Bem vindo ' + name)
```

Na linha 02 chamamos o método **_input()_** escrevendo na tela a mensagem `'Digite seu nome:'`.

```
λ python lendoTecladoInputMensagem.py
Digite seu nome:Jose
Bem vindo Jose
```

## Regras básicas de _Strings_

O valor de uma _string_ deve estar entre aspas simples ou aspas duplas, a linguagem _Python_ permite utilizar ambos os delimitadores, tornando mais flexível e fácil o trabalho do programador.

```python
#Exemplo - liberdade em usar aspas simples ou duplas
>>> uma_string = 'Sou uma string valida'
>>> print(uma_string)
Sou uma string valida

>>> outra_string = "Sou outra string valida"
>>> print(outra_string)
Sou outra string valida
```

No exemplo abaixo, o valor da variável **_pergunta_** permite utilizar aspas simples no seu valor, uma vez que ele se inicia com aspas duplas. Se tivéssemos inicializado com aspas simples, poderíamos utilizar as aspas duplas dentro do valor da variável.

```python
#Exemplo - flexibilidade no uso de aspas simples e duplas
>>> pergunta = "Quem disse a frase - 'SER OU NAO SER, EIS A QUESTAO!' ?"
>>> print(pergunta)
Quem disse a frase - 'SER OU NAO SER, EIS A QUESTAO!' ?
```

## Caracteres em branco e de _escape_

Um _string_ em branco pode ser representada pelo simples valor _" "_, e uma _string_ vazia somente abrindo e fechando aspas sem digitar qualquer valor dentro dela.

```python
#Exemplo - String vazia e em branco
>>> string_em_branco = " "
>>> string_vazia = ""     
>>> len(string_em_branco) 
1                         
>>> len(string_vazia)     
0
```

Observe que uma string vazia possui tamanho ZERO.

Outra forma de representar _strings_ em branco é através do uso de caracteres de escape como:
*  o “\t” que representa o _tab_ do teclado, ou 4 espaços em branco;
* o “\n” que representa uma nova linha;

```python
#Exemplo - \n e \t
>>> frase = "\t O uso de caracteres de escape eh comum. \n Experimente no shell"
>>> print(frase)
         O uso de caracteres de escape eh comum.
 Experimente no shell

>>> frase = "Usando somente \t\t\t o TAB"
>>> print(frase)
Usando somente                   o TAB

>>> frase = "Usando somente \n\n\n o NOVA LINHA"
>>> print(frase)
Usando somente


 o NOVA LINHA                     
```

As aspas simples e duplas também podem ser representadas como caracteres de _escape_:
* \’ representando aspas simples
* \” representando aspas simples

```python
#Exemplo - usando \' e \"
>>> texto = 'Exemplo de \'aspas simples\''
>>> print(texto)
Exemplo de 'aspas simples'

>>> texto = "Exemplo de \"aspas duplas\" "
>>> print(texto)
Exemplo de "aspas duplas"
```

## Comparação entre **_strings_**

Podemos utilizar operadores relacionais (>, &lt;, ==, !=, &lt;=, >=) com **_strings_**.

As **_strings_** têm como características serem **_case sensitives_**, então duas **_strings_** são consideradas iguais se possuem os mesmos caracteres, desta forma ‘a’ é diferente de ‘A’.

Quando comparamos **_strings_**, a classificação que elas obedecem é a ordem alfabética, as palavras iniciando em maiúsculo são _menores_ que as palavras iniciando em minúsculo. As **_strings_** numéricas, além de obedecerem a ordem alfabética, são menores quando comparadas com **_strings_** alfabéticas.

Experimente os exemplos abaixo.

```python
#Comparando strings
>>> str1 = "abacate"
>>> str2 = "casa"

>>> str1 > str2
False
>>> str1 < str2
True

>>> str3 = "Aba"
>>> str1 > str3
True
>>> str3 > str1
False

>>> str4 = "10"
>>> str5 = "2"
>>> str4 > str5
False
>>> str5 > str4
True

>>> str1 > str4
True
>>> str3 > str4
True
```

## **_String_** multilinha

Podemos representar múltiplas linhas em uma **_string_** através do uso do escape _“\n”_, como no exemplo:

```python
#Exemplo - multilinha usando \n
>>> texto = "Paragrafo 1\nParagrafo 2"
>>> print(texto)
Paragrafo 1
Paragrafo 2
```

Mas uma alternativa é através do uso de três aspas simples ('''), veja como fica o exemplo anterior no **_shell_**:

```python
#Exemplo - multilinha usando ''' no shell
>>> texto = '''Paragrafo 1
... Paragrafo 2'''
>>> print(texto)
Paragrafo 1
Paragrafo 2
```

Ou criando um arquivo **_.py_** e executando:

```python
#Programa multilinha.py
texto = '''
Paragrafo 1
Paragrafo 2
Paragrafo 3
'''
print(texto)
```

```
#Exemplo - execução de multilinha.py
Paragrafo 1
Paragrafo 2
Paragrafo 3
```

Usando multilinhas também tem mais flexibilidade no uso de aspas simples e duplas:

```python
#Exemplo - flexibilidade com multilinhas no shell
>>> texto = '''Como se traduz a expressao: "He's a boy" ?'''
>>> print(texto)
Como se traduz a expressao: "He's a boy" ?
```

## Métodos e funções úteis para **_strings_**

### Função _len( )_

A função **_len( )_** retorna o tamanho ou a quantidade de caracteres de uma _string_.

```python
#Função len() em ação no shell
>>> len('quantos caracteres eu possuo?')
29
```

<table>
  <tr>
   <td>Agora é a sua vez!
   </td>
  </tr>
  <tr>
   <td>Faça um programa que leia o nome do usuário e mostre a quantidade de caracteres do nome.
   </td>
  </tr>
</table>

### Método _title( )_

Um método é uma ação que pode ser executada em um pedaço de dados. Diferente de uma função simples, como a **_len( )_**, a sintaxe para executar um método é usando o nome da variável, um ponto (.) e o nome do método.

O primeiro método que vamos aprender das **_strings_** é o _title_ que coloca o primeiro caractere em maiúsculo, das strings separadas por espaço.

```python
#Método title() em ação no shell
>>> nome = 'joao carlos'
>>> print(nome.title())
Joao Carlos

>>> nome = 'lara maria'.title()
>>> print(nome)
Lara Maria
```

### Método _upper( )_ e _lower( )_

Transformam a _string_ toda em maiúsculo (_upper_) ou em minúsculo (_lower_).

```python
#Método upper() e lower() em ação no shell
>>> nome = 'APrendendo Python'
>>> print(nome.lower())
aprendendo python

>>> print(nome.upper())
APRENDENDO PYTHON
```

### Métodos _isupper( )_ e _islower( )_

Os métodos **_isupper()_** e **_islower()_** retornam um valor booleano: **_True_** ou **_False_**.

O método **_isupper()_** retorna verdade (**_True_**) se a **_string_** estiver em maiúsculo e falso (**_False_**) se não estiver em maiúsculo. E o método **_islower()_** retorna verdade (**_True_**) se a **_string_** estiver em minúsculo e falso (**_False_**) se não estiver em minúsculo.

```python
#Método isupper() e islower() em ação no shell
>>> "Joao".isupper()
False
>>> "Joao".islower()
False
>>> "casa".islower()
True
>>> "ASA".isupper()
True
>>> "12".islower()
False
>>> "12".isupper()
False
>>> "asa123".islower()
True
>>> "12asa".islower()
True
>>> "CASA_12".isupper()
True
>>> "__CARRO_".isupper()
True
```

### Métodos _isalpha( ), isalnum( ),  isdecimal( ), isspace( ), istitle( )_

O método **_isalpha( )_** retorna **_True_** se a **_string_** é formada somente de letras e não é vazia.

O método **_isalnum( )_** retorna **_True_** se a **_string_** é formada de letras e números, e não é vazia.

O método **_isdecimal( )_** retorna **_True_** se a **_string_** é formada somente de números e não é vazia.

O método **_isspace( )_** retorna **_True_** se a **_string_** é formada somente de espaços, linhas em branco e não é vazia.

O método **_istitle( )_** retorna **_True_** se a **_string_** possui palavras que iniciam com a letra maiúscula.

```python
#Métodos isX() em ação no shell
>>> "Python".isalpha()
True
>>> "Python3".isalnum()
True
>>> "Python 3.0".isalnum()
False
>>> "Python3.0".isalnum()
False
>>> "1234".isdecimal()
True
>>> "3.14".isdecimal()
False
>>> "   ".isspace()
True
>>> "Curso De Python".istitle()
True
>>> "Curso de Python".istitle()
False
```

### Métodos **_startswith(), endswith()_**

O método **_startswith( )_** retorna **_True_** se a **_string_** possui um determinado prefixo, ou, se a **_string_** inicia com um determinado valor.

O método **_endswith( )_** retorna **_True_** se a **_string_** possui um determinado sufixo, ou, se a **_string_** termina com um determinado valor.

```python
#startswith(), endswith() em ação no shell
>>> "Sr. Jose".startswith("Sr.")
True
>>> "amorzinho".endswith("zinho")
True
>>> "linguagem".startswith("L")
False
```

### Métodos **_rjust(), ljust(), center()_**

São métodos que inserem espaços em branco na **_string_** para completar um determinado tamanho. O tamanho é enviado como argumento do método.

O método **_rjust()_** insere uma quantidade de espaços em branco no lado esquerdo da **_string_**. A **_string_** fica ao lado direito (right).

O método **_ljust()_** insere uma quantidade de espaços em branco no lado direito da **_string_**. A **_string_** fica ao lado esquerdo (left).

O método **_center()_** insere uma quantidade de espaços em branco no lado direito e esquerdo da **_string_**. A **_string_** fica centralizada (center).

```python
#rjust(), ljust(), center() em ação no shell
>>> "Python".rjust(15)
'         Python'

>>> "Python".ljust(15)
'Python         '

>>> "Python".center(10)
'  Python  '
```

É possível indicar qual caractere inserir, em vez de utilizar o espaço em branco.

```python
#rjust(), ljust(), center() substituindo o espaço em branco
>>> "Python".rjust(15, '*')
'*********Python'

>>> "Python".ljust(15, '#')
'Python#########'

>>> "Python".center(10, '-')
'--Python--'
```

### Métodos _strip( ), rstrip( ), lstrip( )_

Método de _strip_ em uma _string_, significa remover espaços ou caracteres em branco, que não são visíveis, da string.

```python
#strip em ação no shell
>>> mensagem = "  alguma mensagem   "
>>> len(mensagem)
20
>>> mensagem = mensagem.strip()
>>> len(mensagem)
15
>>> print(mensagem)
alguma mensagem
```

Este método é bastante utilizado para diminuir o tamanho do valor de uma string que possui espaços em branco no início ou no final. Veja no exemplo anterior que somente os espaços em branco das extremidades são removidos. Se existir espaços em branco entre strings dentro do valor, eles não serão removidos.

Além do _strip( )_, _Python_ possui o _rstrip( )_ que remove espaços em branco do lado direito (_r_ de _right_) da _string_ e o _lstrip( )_ que remove espaços em branco do lado esquerdo (_l_ de _left_).


```python
#lstrip() e rstrip() em ação no shell
>>> message = '   \t Alguma mensagem aqui. \t   '
>>> print(message)
         Alguma mensagem aqui.

>>> print(message.lstrip())
Alguma mensagem aqui.

>>> print(message.rstrip())
         Alguma mensagem aqui.
```

### Funções _ord( ), chr( )_

Os caracteres nas linguagens de programação são representados por números. Existe uma tabela, denominada **_Unicode_** que mapeia o valor de um caractere em sua representação numérica (veja [tabela](https://www.utf8-chartable.de/)).

A função **_ord( )_** retorna o valor numérico de um caractere e a função **_chr( )_** retorna o caractere de um valor numérico.

```python
#ord() e chr() em ação no shell
>>> ord("A")
65

>>> ord("C")
67

>>> ord("S")
83

>>> chr(90)
'Z'

>>> print(chr(67)+chr(65)+chr(83)+chr(65))
CASA
```

Uma forma interessante de transformar um caractere numérico para seu valor numérico é subtraindo da referência do valor do caractere ‘0’. Observe o código abaixo.

```python
#ord() calculando valor numérico
>>> ord('0')
48

>>> ord('9')
57

>>> ord('9') - ord('0')
9

>>> ord('7') - ord('0')
7
```

### _f-strings_

A partir do _Python 3.6_, podemos utilizar a sintaxe _f-strings_ para formatar _strings_. Veja o exemplo.

```python
#f-strings em ação no shell
>>> nome = 'Pedro Alvares'
>>> sobrenome = 'Cabral'
>>> mensagem = f"Seja bem vindo, {sobrenome} - {nome}"
>>> print(mensagem)
Seja bem vindo, Cabral - Pedro Alvares
```

A sintaxe _f-strings_ se inicia com a letra “f” antes das aspas duplas, e no valor da string que estamos criando é possível inserir diretamente os valores armazenados em variáveis, representadas entre chaves (“{ }”).

No exemplo acima, a instrução `f"Seja bem vindo, {sobrenome} - {nome}" ,` gera uma _string_ de valor “_Seja bem vindo, Cabral - Pedro Alvares_”,  lendo os valores da variável _sobrenome_ e da variável _nome_, ambos dentro das chaves { }. Se você não colocar entre chaves, serão interpretados pela linguagem como valores simples.

```python
#Entendendo o acesso de variáveis em f-strings
>>> nome = 'Pedro Alvares'
>>> sobrenome = 'Cabral'
>>> mensagem = f"Seja bem vindo, {sobrenome} - {nome}"
>>> print(mensagem)
Seja bem vindo, Cabral - Pedro Alvares

>>> mensagem = f"Seja bem vindo, sobrenome - nome"
>>> print(mensagem)
Seja bem vindo, sobrenome - nome
```

Também utilizando **_f-string_** podemos imprimir valores numéricos sem a necessidade de utilizar a função **_str( )_**.

```python
#Imprimindo números com f-strings
>>> num = 10
>>> print(f"Meu numero preferido eh o numero {num}")
Meu numero preferido eh o numero 10
```

### _r-string_

Semelhante ao **_f-strings_** temos o comando **_r-string_** que permite ler a **_string_** ignorando os caracteres de escape e imprimindo a “\”.

```python
#Imprimindo com r-strings
>>> print(r'Meu nome \t Joao')
Meu nome \t Joao

>>> print(r"C:\temp")
C:\temp
```

Ler uma **_string_** com **_r-string_** é bastante útil quando o valor representa um caminho de pastas ou diretórios de uma máquina, que contém muitas “\”.

## Substituindo caracteres

Utilizamos o método **_replace( )_** para remover caracteres em uma **_string_**. Este método não modifica o valor da variável ou da _string_, mas retorna uma nova _string_.

```python
#Sintaxe replace()
<str>.replace(<str_substituir>, <str_novo>[, <max_ocorrencia>])

<max_ocorrencia>: indica a quantidade máxima 
de ocorrências a serem substituídas.
```

Apesar de ser um método de substituição, você pode substituir uma parte da string pelo caractere vazio “”.

Experimente no seu **_shell_**.

```python
#Uso do replace( )
>>> "azul, preto, banana, amarelo".replace(" banana,", "")
'azul, preto, amarelo'

>>> texto = "Estou aprendendo Java"
>>> texto.replace("Java", "Python")
'Estou aprendendo Python'

>>> texto = "casa, comida, roupa, sapato"
>>> texto.replace(", ", "-> ")
'casa-> comida-> roupa-> sapato'

>>> texto.replace(", ", "# ", 1)
'casa# comida, roupa, sapato'
```

No último caso, executamos o _replace( )_ passando o número de ocorrências a serem alteradas igual a 1, neste caso, somente a primeira ocorrência foi substituída.

## Incorporando valores em uma **_string_** usando **_%s_**

Apesar de não ser um método ou função, faltou comentarmos como inserir valores em uma **_string_** usando o operador %.

Podemos inserir valores em uma **_string_** através da representação **_%s_** e incluir o valor ou variável, posteriormente, como no exemplo:

```python
#Inserindo valores em uma string com %
>>> num = 10
>>> mensagem = "Meu numero preferido eh o numero %s"

>>> print(mensagem % num)
Meu numero preferido eh o numero 10

>>> print(mensagem % 20)
Meu numero preferido eh o numero 20
```

Observe que temos a variável _num_ recebendo o valor 10 e a variável _mensagem_ com o valor `"Meu numero preferido eh o numero %s"`. O _token %s_ indica a posição onde será inserido valores na **_string_**.

Na instrução `print(mensagem % num)`, novamente utilizando o %, indicamos que o valor usado na **_string_** será da variável _num_. Analogamente, na instrução `print(mensagem % 20)`,  o valor utilizado será o número 20.

Podemos passar múltiplos valores, passando entre parênteses os valores a serem utilizados:

```python
#Inserindo múltiplos valores em uma string com %
>>> x = 10
>>> y = 20
>>> template = "O valor de %s multiplicado por %s eh igual a %s"
>>> mensagem = template % (x, y, x*y)
>>> print(mensagem)
O valor de 10 multiplicado por 20 eh igual a 200
```

No algoritmo acima estamos utilizando 2 variáveis numéricas e 2 variáveis do tipo _string_. A variável _template_ armazenará somente a _string _padrão da mensagem, contendo os _%s_. Já a variável _mensagem_ armazenará o valor de _template_ com os valores inseridos: valor de _x_, valor de _y_ e o valor da multiplicação _x * y_.

Agora temos 3 operadores “matemáticos” que podem ser utilizados com **_strings_**: + (concatenação), * (replicação) e % (inserção de valores).


## Função **_print()_**

A função **_print()_** possui dois parâmetros opcionais:

* **_end_** - indica o caracter de final de linha
* **_sep_** - indica o caracter separador de argumentos

Entenda a utilização dos dois parâmetros opcionais no exemplo seguinte.

```python
#Algoritmo - printOpcionais.py
print("Experimentando")
print("com texto livre")

print("Experimentando", end=" ")
print("com texto livre")

print("Multiplos", "textos", "exemplo")

print("Multiplos", "textos", "exemplo", sep="-")
```

Na **_linha 04_** usamos o parâmetro `end=" "`, indicando que no final do texto impresso pelo **_print_**, não pularemos uma linha, mas usaremos um espaço em branco.

Podemos passar mútiplos valores no **_print_**, como na linha 07, os valores serão impressos separados por um espaço em branco, por padrão. Mas na linha 09 modificamos o **_print_** para separar os elementos com um hífen (**_“-”_**).

Observe a execução.

```
#Execução - printOpcionais.py
Experimentando
com texto livre
Experimentando com texto livre
Multiplos textos exemplo
Multiplos-textos-exemplo
```

## Erros comuns

O método **_ord( )_** só pode ser aplicado a caracteres, não aceitando **_strings_** com mais de um caractere.

```python
#Erro com ord()
>>> ord('abx')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: ord() expected a character, but string of length 3 found
```