4. De tekenreeksen

4.1. Script [str_01]: notatie van tekenreeksen
Het script [str_01] is als volgt:
# tekenreeksen
# drie mogelijke notaties
chaine1 = "un"
chaine2 = 'deux'
chaine3 = """hélène va au
marché acheter des légumes"""
# weergave
print(f"chaine1=[{chaine1}], chaine2=[{chaine2}], chaine3=[{chaine3}]")
Opmerkingen
- regel 3: een tekenreeks afgebakend door aanhalingstekens ";
- regel 4: een tekenreeks afgebakend door apostrofs ';
- regel 5: een tekenreeks die wordt begrensd door drievoudige aanhalingstekens """. In dit geval kan de tekenreeks over meerdere regels lopen;
De resultaten zijn als volgt:
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]: de methoden van de klasse <str>
Het script [str_02] toont enkele methoden van de klasse <str>, de klasse voor tekenreeksen:
# functies op tekenreeksen
# tekenreeks in kleine letters
print(f"'ABCD'.lower()={'ABCD'.lower()}")
# tekenreeks in hoofdletters
print(f"'abcd'.upper()={'abcd'.upper()}")
# teken nr. 2
print(f"'cheval[2]={'cheval'[2]}")
# substring met de tekens 5 en 6
print(f"'caractères accentués'[5:7]={'caractères accentués'[5:7]}")
# deelreeks vanaf en met inbegrip van teken 4
print(f"'caractères accentués'[4:]={'caractères accentués'[4:]}")
# deelreeks tot en met teken 6
print(f"'caractères accentués'[:5]={'caractères accentués'[:5]}")
# lengte van de reeks
print(f"len('123')={len('123')}")
# verwijdering van spaties voor en na de tekenreeks
print(f"' abcd '.strip()=[{' abcd '.strip()}]")
# verwijdering van spaties na de tekenreeks
print(f"' abcd '.rstrip()=[{' abcd '.rstrip()}]")
# verwijdering van spaties vóór de tekenreeks
print(f"' abcd '.lstrip()=[{' abcd '.lstrip()}]")
# de term 'spatie' omvat in feite verschillende tekens
str = ' \r\nabcd \t\f'
print(f"str.strip()=[{str.strip()}]")
# een substring vervangen door een andere
print(f"'abcd'.replace('a','x')={'abcd'.replace('a', 'x')}")
print(f"'abcd'.replace('ab','xy')={'abcd'.replace('ab', 'xy')}")
# zoeken naar een subreeks: geeft de positie terug of -1 als de subreeks niet is gevonden
print(f"'abcd'.find('bc')={'abcd'.find('bc')}")
print(f"'abcd'.find('bc')={'abcd'.find('Bc')}")
# begin van een tekenreeks
print(f"'abcd'.startswith('ab')={'abcd'.startswith('ab')}")
print(f"'abcd'.startswith('x')={'abcd'.startswith('x')}")
# einde van een tekenreeks
print(f"'abcd'.endswith('cd')={'abcd'.endswith('cd')}")
print(f"'abcd'.endswith('x')={'abcd'.endswith('x')}")
# omzetting van een lijst met tekenreeksen naar een tekenreeks
print(f"'[X]'.join(['abcd', '123', 'èéà'])={'[X]'.join(['abcd', '123', 'èéà'])}")
print(f"''.join(['abcd', '123', 'èéà'])={''.join(['abcd', '123', 'èéà'])}")
# overgang van een tekenreeks naar een lijst met tekenreeksen
print(f"'abcd 123 cdXY'.split('cd')={'abcd 123 cdXY'.split('cd')}")
# woorden uit een tekenreeks ophalen
print(f"'abcd 123 cdXY'.split(None)={'abcd 123 cdXY'.split(None)}")
De opmerkingen in combinatie met de verkregen resultaten volstaan om het script te begrijpen. De resultaten zijn als volgt:
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
'paard[2]=e
'tekens met accenten'[5:7]=tè
'tekens met accenten'[4:]=tekens met accenten
'tekens met accenten'[:5]=teken
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]: codering van tekenreeksen (1)
Het script [str_03] behandelt basisbegrippen over de codering van tekenreeksen:
# tekencodering
# tekenreeks van het type str
str = "hélène va au marché acheter des légumes"
print(f"str=[{str}, type={type(str)}]")
# UTF-8-codering
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)}")
# iso-8859-1-codering
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)}")
# codering 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)}")
Het coderen van een tekenreeks van het type <str> levert een binaire reeks op waarin elk teken van de reeks wordt weergegeven door één of meerdere bytes. Er bestaan verschillende soorten codering. Het bovenstaande script behandelt de twee meest gangbare in het Westen: „utf-8” en „iso-8859-1”, ook wel „latin1” genoemd.
Het principe van codering/decodering wordt hieronder geïllustreerd (ref. |https://realpython.com/python-encodings-guide/ |):

Opmerkingen
- regels 4-5: de oorspronkelijke tekenreeks die gecodeerd gaat worden. Instanties van het type <str> zijn Unicode-tekenreeksen |https://docs.python.org/3/howto/unicode.html|, |https://realpython.com/python-encodings-guide/ |;
- regels 6-11: twee manieren om een tekenreeks te coderen in UTF68:
- regel 8: str.encode('utf-8) ;
- regel 10: bytes(str, 'utf-8');
- regels 12-17: we doen hetzelfde met de codering 'iso-8859-1';
- regels 18-23: 'latin1' is een andere naam voor de codering 'iso-8859-1';
De resultaten zijn als volgt:
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
Opmerkingen
- regel 4: we zien dat de tekens met accenten over twee bytes zijn gecodeerd:
- é: [\xc3\xa9], wat de binaire reeks 11000011 10101001 is;
- è: [\xc3\xa8], wat overeenkomt met de binaire reeks 11000011 10101000;
- regels 7: met de ISO-8859-1-codering worden deze twee tekens met accenten verschillend gecodeerd:
- é: [\xe9], wat overeenkomt met de binaire reeks 11101001;
- è: [\xe8], wat overeenkomt met de binaire reeks 11101000;
4.4. Script [str_04]: codering van tekenreeksen (2)
Het script [str_04] presenteert twee andere coderingstypen: 'base64' en 'quoted-printable'. Deze twee coderingen coderen geen Unicode-tekenreeksen, maar binaire objecten. Wanneer u bijvoorbeeld een Word-document als bijlage bij een e-mail voegt, wordt dit onderworpen aan een van deze twee coderingen, afhankelijk van het gebruikte e-mailprogramma. Dit geldt voor de meeste bijgevoegde bestanden.
Het script is als volgt:
# codering / decodering
import codecs
# tekenreeks
print("---- chaîne unicode")
str1 = "hélène va au marché acheter des légumes"
print(f"str1=[{str1}], type(str1)={type(str1)}")
# codering utf-8
print("---- chaîne unicode -> binaire utf-8")
bytes1 = bytes(str1, "utf-8")
print(f"bytes1=[{bytes1}], type(bytes1)={type(bytes1)}")
# decodering 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}")
# codering 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)}")
# decodering 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}")
# decoderingsfout - bytes1 is in utf-8 - wordt gedecodeerd naar 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)}")
# UTF-8-codering van een Unicode-tekenreeks
print("---- chaîne unicode -> binaire utf-8")
bytes3 = codecs.encode(str1, "utf-8")
print(f"bytes3=[{bytes3}], type(bytes3)={type(bytes3)}")
# Base64-codering van een binaire tekenreeks UTF-8
print("---- binaire utf-8 -> binaire base64")
bytes4 = codecs.encode(bytes1, "base64")
print(f"bytes4=[{bytes4}], type(bytes4)={type(bytes4)}")
# terug naar de oorspronkelijke Unicode-tekenreeks
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)}")
# codering van een binaire tekenreeks in quoted-printable
print("---- binaire utf-8 -> binaire quoted-printable")
str7 = codecs.encode(bytes1, "quoted-printable")
print(f"str7=[{str7}], type(str7)={type(str7)}")
# terug naar de oorspronkelijke Unicode-string
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)}")
Opmerkingen
- regel 2: met de module [codecs] kunnen de coderingen 'base64' en 'quoted-printable' worden uitgevoerd. Er zijn nog veel meer mogelijkheden;
- regels 4-7: de Unicode-string die verschillende coderingen zal ondergaan;
- regels 9-12: UTF-8-codering. Dit levert een binair bestand op;
- regels 14-18: UTF-8-decodering om terug te keren naar de oorspronkelijke Unicode-string;
- regels 20-29: hetzelfde proces wordt herhaald met de codering 'iso-8859-1';
- regels 31-34: er wordt een decoderingsfout weergegeven:
- regel 33: bytes1 is een binaire tekenreeks die is gecodeerd in 'utf-8'. Deze wordt gedecodeerd naar 'iso-8859-1';
- regels 36-39: een andere manier om een tekenreeks in utf-8 te coderen met de module [codecs];
- regels 41-44: een binaire 'utf-8'-string wordt gecodeerd in 'base64';
- regels 46-49: laten zien hoe je van de binaire 'base64'-tekenreeks teruggaat naar de oorspronkelijke Unicode-tekenreeks;
- regels 51-59: dit proces wordt herhaald met een 'quoted-printable'-codering in plaats van 'base64';
De resultaten zijn als volgt:
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
- regels 14-15: een UTF-8-binaire reeks wordt gedecodeerd naar een Unicode-tekenreeks met de verkeerde decoder 'iso-8859-1'. Daardoor zijn sommige gegenereerde Unicode-tekens onjuist, in dit geval de tekens met accenten;
- regels 18-19: de 'base64'-codering bestaat uit het gebruik van 64 tekens ASCII (gecodeerd op 7 bits) om een willekeurig binair bestand te coderen. Dit vergroot, zoals te zien is, de grootte van de binaire reeks;
- regels 22-23: de 'quoted-printable'-codering maakt eveneens gebruik van de tekens ASCII (gecodeerd op 7 bits) om willekeurige binaire gegevens te coderen;
We moeten niet vergeten dat wanneer we een binair bestand ontvangen, bijvoorbeeld via het internet, dat een tekst vertegenwoordigt, we de coderingen moeten kennen die erop zijn toegepast om de tekst te kunnen achterhalen.