4. As cadeias de caracteres

4.1. Script [str_01]: notação das cadeias de caracteres
O script [str_01] é o seguinte:
# cadeias de caracteres
# três forma de representação possíveis
chaine1 = "un"
chaine2 = 'deux'
chaine3 = """hélène va au
marché acheter des légumes"""
# exibição
print(f"chaine1=[{chaine1}], chaine2=[{chaine2}], chaine3=[{chaine3}]")
Comentários
- linha 3: uma cadeia delimitada por aspas ";
- linha 4: uma cadeia delimitada por apóstrofos ';
- linha 5: uma cadeia delimitada por aspas triplas """. Neste caso, a cadeia pode estender-se por várias linhas;
Os resultados são os seguintes:
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/strings/str_01.py
chaine1=[un], chaine2=[deux], chaine3=[hélène va au
marché acheter des légumes]
Process finished with exit code 0
4.2. Script [str_02]: os métodos da classe <str>
O script [str_02] apresenta alguns dos métodos da classe <str>, que é a classe das cadeias de caracteres:
# funções sobre cadeias de caracteres
# cadeia de caracteres em minúsculas
print(f"'ABCD'.lower()={'ABCD'.lower()}")
# cadeia de caracteres em maiúsculas
print(f"'abcd'.upper()={'abcd'.upper()}")
# caractere n.º 2
print(f"'cheval[2]={'cheval'[2]}")
# subcadeia com os caracteres 5 e 6
print(f"'caractères accentués'[5:7]={'caractères accentués'[5:7]}")
# subcadeia a partir do caractere 4, inclusive
print(f"'caractères accentués'[4:]={'caractères accentués'[4:]}")
# subcadeia até ao carácter 6, excluído
print(f"'caractères accentués'[:5]={'caractères accentués'[:5]}")
# comprimento da cadeia
print(f"len('123')={len('123')}")
# eliminação dos espaços antes e depois da cadeia
print(f"' abcd '.strip()=[{' abcd '.strip()}]")
# remoção dos espaços a seguir à cadeia
print(f"' abcd '.rstrip()=[{' abcd '.rstrip()}]")
# remoção dos espaços à esquerda da cadeia
print(f"' abcd '.lstrip()=[{' abcd '.lstrip()}]")
# o termo «espaço» abrange, na verdade, diferentes caracteres
str = ' \r\nabcd \t\f'
print(f"str.strip()=[{str.strip()}]")
# substituição de uma subcadeia por outra
print(f"'abcd'.replace('a','x')={'abcd'.replace('a', 'x')}")
print(f"'abcd'.replace('ab','xy')={'abcd'.replace('ab', 'xy')}")
# procura de uma subcadeia: devolve a posição ou -1 se a subcadeia não for encontrada
print(f"'abcd'.find('bc')={'abcd'.find('bc')}")
print(f"'abcd'.find('bc')={'abcd'.find('Bc')}")
# início de uma cadeia
print(f"'abcd'.startswith('ab')={'abcd'.startswith('ab')}")
print(f"'abcd'.startswith('x')={'abcd'.startswith('x')}")
# fim de uma cadeia
print(f"'abcd'.endswith('cd')={'abcd'.endswith('cd')}")
print(f"'abcd'.endswith('x')={'abcd'.endswith('x')}")
# conversão de uma lista de cadeias numa cadeia
print(f"'[X]'.join(['abcd', '123', 'èéà'])={'[X]'.join(['abcd', '123', 'èéà'])}")
print(f"''.join(['abcd', '123', 'èéà'])={''.join(['abcd', '123', 'èéà'])}")
# passagem de uma cadeia para uma lista de cadeias
print(f"'abcd 123 cdXY'.split('cd')={'abcd 123 cdXY'.split('cd')}")
# recuperar as palavras de uma cadeia
print(f"'abcd 123 cdXY'.split(None)={'abcd 123 cdXY'.split(None)}")
Os comentários, juntamente com os resultados obtidos, são suficientes para compreender o script. Os resultados são os seguintes:
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/strings/str_02.py
'ABCD'.lower()=abcd
'abcd'.upper()=ABCD
'cavalo[2]=e
'caracteres acentuados'[5:7]=tè
'caracteres acentuados'[4:]=caracteres acentuados
'caracteres acentuados'[:5]=carac
len('123')=3
' abcd '.strip()=[abcd]
' abcd '.rstrip()=[ abcd]
' abcd '.lstrip()=[abcd ]
str.strip()=[abcd]
'abcd'.replace('a','x')=xbcd
'abcd'.replace('ab','xy')=xycd
'abcd'.find('bc')=1
'abcd'.find('bc')=-1
'abcd'.startswith('ab')=True
'abcd'.startswith('x')=False
'abcd'.endswith('cd')=True
'abcd'.endswith('x')=False
'[X]'.join(['abcd', '123', 'èéà'])=abcdQZXW2HTMLBW1hdZQX123QZXW2HTMLBW1hdZQXèéà
''.join(['abcd', '123', 'èéà'])=abcd123èéà
'abcd 123 cdXY'.split('cd')=['ab', ' 123 ', 'XY']
'abcd 123 cdXY'.split(None)=['abcd', '123', 'cdXY']
Process finished with exit code 0
4.3. Script [str_03]: codificação de cadeias de caracteres (1)
O script [str_03] apresenta noções sobre a codificação de cadeias de caracteres:
# codificação de caracteres
# cadeia de caracteres do tipo str
str = "hélène va au marché acheter des légumes"
print(f"str=[{str}, type={type(str)}]")
# codificação utf-8
print("--- utf-8")
bytes1 = str.encode('utf-8')
print(f"bytes1={bytes1}, type={type(bytes1)}")
bytes2 = bytes(str, 'utf-8')
print(f"bytes2={bytes2}, type={type(bytes2)}")
# codificação iso-8859-1
print("--- iso-8859-1")
bytes1 = str.encode('iso-8859-1')
print(f"bytes1={bytes1}, type={type(bytes1)}")
bytes2 = bytes(str, 'iso-8859-1')
print(f"bytes2={bytes2}, type={type(bytes2)}")
# codificação latin1=iso-8859-1
print("--- latin1")
bytes1 = str.encode('latin1')
print(f"bytes1={bytes1}, type={type(bytes1)}")
bytes2 = bytes(str, 'latin1')
print(f"bytes2={bytes2}, type={type(bytes2)}")
A codificação de uma cadeia de caracteres do tipo <str> produz uma cadeia binária em que cada caractere da cadeia é representado por um ou mais octetos. Existem diferentes tipos de codificação. O script acima apresenta os dois mais comuns no Ocidente: «utf-8» e «iso-8859-1», também conhecido como «latin1».
O princípio da codificação/decodificação é ilustrado abaixo (ref. |https://realpython.com/python-encodings-guide/ |):

Comentários
- linhas 4-5: a cadeia de caracteres inicial que vai ser codificada. As instâncias do tipo <str> são cadeias Unicode |https://docs.python.org/3/howto/unicode.html|, |https://realpython.com/python-encodings-guide/ |;
- linhas 6-11: duas formas de codificar uma cadeia de caracteres em UTF68:
- linha 8: str.encode('utf-8);
- linha 10: bytes(str, 'utf-8');
- linhas 12-17: repetimos o mesmo procedimento com a codificação «iso-8859-1»;
- linhas 18-23: «latin1» é outro nome para a codificação «iso-8859-1»;
Os resultados são os seguintes:
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/strings/str_03.py
str=[hélène va au marché acheter des légumes, type=<class 'str'>
--- utf-8
bytes1=b'h\xc3\xa9l\xc3\xa8ne va au march\xc3\xa9 acheter des l\xc3\xa9gumes', type=<class 'bytes'>
bytes2=b'h\xc3\xa9l\xc3\xa8ne va au march\xc3\xa9 acheter des l\xc3\xa9gumes', type=<class 'bytes'>
--- iso-8859-1
bytes1=b'h\xe9l\xe8ne va au march\xe9 acheter des l\xe9gumes', type=<class 'bytes'>
bytes2=b'h\xe9l\xe8ne va au march\xe9 acheter des l\xe9gumes', type=<class 'bytes'>
--- latin1
bytes1=b'h\xe9l\xe8ne va au march\xe9 acheter des l\xe9gumes', type=<class 'bytes'>
bytes2=b'h\xe9l\xe8ne va au march\xe9 acheter des l\xe9gumes', type=<class 'bytes'>
Process finished with exit code 0
Comentários
- linha 4: verifica-se que os caracteres acentuados foram codificados em dois bytes:
- é: [\xc3\xa9], que corresponde à sequência binária 11000011 10101001;
- è: [\xc3\xa8], que corresponde à sequência binária 11000011 10101000;
- linhas 7: com a codificação ISO-8859-1, estes dois caracteres acentuados são codificados de forma diferente:
- é: [\xe9], que corresponde à sequência binária 11101001;
- è: [\xe8], que corresponde à sequência binária 11101000;
4.4. Script [str_04]: codificação de cadeias de caracteres (2)
O script [str_04] apresenta dois outros tipos de codificação: «base64» e «quoted-printable». Estas duas codificações não codificam cadeias de caracteres Unicode, mas sim objetos binários. Por exemplo, quando se anexa um documento do Word a um e-mail, este será submetido a uma destas duas codificações, dependendo do programa de e-mail utilizado. Este será o caso da maioria dos ficheiros anexados.
O script é o seguinte:
# codificação/descodificação
import codecs
# cadeia
print("---- chaîne unicode")
str1 = "hélène va au marché acheter des légumes"
print(f"str1=[{str1}], type(str1)={type(str1)}")
# codificação utf-8
print("---- chaîne unicode -> binaire utf-8")
bytes1 = bytes(str1, "utf-8")
print(f"bytes1=[{bytes1}], type(bytes1)={type(bytes1)}")
# descodificação utf-8
print("---- binaire utf-8 -> chaîne unicode")
str2 = bytes1.decode("utf-8")
print(f"str2=[{str2}], type(str2)={type(str2)}")
print(f"str2==str1={str2 == str1}")
# codificação iso-8859-1
print("---- chaîne unicode -> binaire iso-8859-1")
bytes2 = bytes(str1, "iso-8859-1")
print(f"bytes2=[{bytes2}], type(bytes2)={type(bytes2)}")
# descodificação iso-8859-1
print("---- binaire iso-8859-1 -> chaîne unicode")
str3 = bytes2.decode("iso-8859-1")
print(f"str3=[{str3}], type(str3)={type(str3)}")
print(f"str3==str1={str3 == str1}")
# erro de descodificação - bytes1 está em UTF-8 - está a ser descodificado em ISO-8859-1
print("--- binaire utf-8 (décodage iso-8859-1) --> chaîne unicode")
str4 = bytes1.decode("iso-8859-1")
print(f"str4=[{str4}], type(str4)={type(str4)}")
# codificação UTF-8 de uma cadeia Unicode
print("---- chaîne unicode -> binaire utf-8")
bytes3 = codecs.encode(str1, "utf-8")
print(f"bytes3=[{bytes3}], type(bytes3)={type(bytes3)}")
# codificação de uma cadeia binária UTF-8 em base64
print("---- binaire utf-8 -> binaire base64")
bytes4 = codecs.encode(bytes1, "base64")
print(f"bytes4=[{bytes4}], type(bytes4)={type(bytes4)}")
# reversão para a cadeia Unicode original
print("---- binaire base64 -> binaire utf-8 -> chaîne unicode")
str6 = codecs.decode(bytes4, "base64").decode("utf-8")
print(f"str6=[{str6}], type(str6)={type(str6)}")
# codificação de uma cadeia binária em quoted-printable
print("---- binaire utf-8 -> binaire quoted-printable")
str7 = codecs.encode(bytes1, "quoted-printable")
print(f"str7=[{str7}], type(str7)={type(str7)}")
# reversão para a cadeia Unicode original
print("---- binaire quoted-printable -> binaire utf-8 -> chaîne unicode")
str8 = codecs.decode(str7, "quoted-printable").decode("utf-8")
print(f"str8=[{str8}], type(str8)={type(str8)}")
Comentários
- linha 2: o módulo [codecs] permite efetuar as codificações «base64» e «quoted-printable». Pode efetuar muitas outras;
- linhas 4-7: a cadeia Unicode que será submetida a várias codificações;
- linhas 9-12: codificação UTF-8. Obtém-se um ficheiro binário;
- linhas 14-18: descodificação UTF-8 para voltar à cadeia Unicode original;
- linhas 20-29: repete-se o mesmo processo com a codificação «iso-8859-1»;
- linhas 31-34: mostra-se um erro de descodificação:
- linha 33: bytes1 é uma cadeia binária codificada em «utf-8». Decodifica-se em «iso-8859-1»;
- linhas 36-39: outra forma de codificar uma cadeia de caracteres em utf-8 com o módulo [codecs];
- linhas 41-44: uma cadeia binária «utf-8» é codificada em «base64»;
- linhas 46-49: mostram como passar da cadeia binária «base64» para a cadeia Unicode original;
- linhas 51-59: repete-se este processo com uma codificação «quoted-printable» em vez de «base64»;
Os resultados são os seguintes:
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/strings/str_04.py
---- chaîne unicode
str1=[hélène va au marché acheter des légumes], type(str1)=<class 'str'>
---- chaîne unicode -> binaire utf-8
bytes1=[b'h\xc3\xa9l\xc3\xa8ne va au march\xc3\xa9 acheter des l\xc3\xa9gumes'], type(bytes1)=<class 'bytes'>
---- binaire utf-8 -> chaîne unicode
str2=[hélène va au marché acheter des légumes], type(str2)=<class 'str'>
str2==str1=True
---- chaîne unicode -> binaire iso-8859-1
bytes2=[b'h\xe9l\xe8ne va au march\xe9 acheter des l\xe9gumes'], type(bytes2)=<class 'bytes'>
---- binaire iso-8859-1 -> chaîne unicode
str3=[hélène va au marché acheter des légumes], type(str3)=<class 'str'>
str3==str1=True
--- binaire utf-8 (décodage iso-8859-1) --> chaîne unicode
str4=[hélène va au marché acheter des légumes], type(str4)=<class 'str'>
---- chaîne unicode -> binaire utf-8
bytes3=[b'h\xc3\xa9l\xc3\xa8ne va au march\xc3\xa9 acheter des l\xc3\xa9gumes'], type(bytes3)=<class 'bytes'>
---- binaire utf-8 -> binaire base64
bytes4=[b'aMOpbMOobmUgdmEgYXUgbWFyY2jDqSBhY2hldGVyIGRlcyBsw6lndW1lcw==\n'], type(bytes4)=<class 'bytes'>
---- binaire base64 -> binaire utf-8 -> chaîne unicode
str6=[hélène va au marché acheter des légumes], type(str6)=<class 'str'>
---- binaire utf-8 -> binaire quoted-printable
str7=[b'h=C3=A9l=C3=A8ne=20va=20au=20march=C3=A9=20acheter=20des=20l=C3=A9gumes'], type(str7)=<class 'bytes'>
---- binaire quoted-printable -> binaire utf-8 -> chaîne unicode
str8=[hélène va au marché acheter des légumes], type(str8)=<class 'str'>
Process finished with exit code 0
- linhas 14-15: um binário UTF-8 é descodificado para uma cadeia Unicode com o descodificador errado «iso-8859-1». Por isso, alguns caracteres Unicode gerados estão incorretos, neste caso os caracteres acentuados;
- linhas 18-19: a codificação «base64» consiste em utilizar 64 caracteres ASCII (codificados em 7 bits) para codificar qualquer ficheiro binário. Isto aumenta, como se pode ver, o tamanho do ficheiro binário da cadeia;
- linhas 22-23: a codificação «quoted-printable» consiste também em utilizar os caracteres ASCII (codificados em 7 bits) para codificar qualquer dado binário;
Recorde-se que, quando se recebe um ficheiro binário — da Internet, por exemplo — que representa um texto, para o recuperar é necessário conhecer as codificações a que foi submetido.