Herken de basisvorm
Laat valid_code een boolean teruggeven voor twee gewone hoofdletters, één koppelteken en drie ASCII-cijfers.
Een label moet uit een vaste combinatie van letters, een scheidingsteken en cijfers bestaan. Alleen controleren of er ergens cijfers in staan is dan te ruim. Je beschrijft de hele toegestane vorm met een klein patroon.
Een reguliere expressie, vaak regex genoemd, beschrijft welke reeksen tekens passen. Python heeft daarvoor de standaardmodule re. Je maakt die beschikbaar met import re, zoals je eerder unicodedata importeerde.
Gewone tekens in een patroon staan voor zichzelf. Een dubbele punt vraagt dus precies een dubbele punt. Met een tekenklasse, zoals [A-Z], kies je één teken uit een bereik.
Bij onze labels bedoelt dat bereik de 26 gewone hoofdletters van A tot en met Z. De klasse [0-9] vraagt één van de tien ASCII-cijfers. Andere alfabetten en andere schrijfwijzen van cijfers horen niet bij dit afgesproken labelformaat.
Een herhalingsaantal achter een onderdeel bepaalt hoe vaak het voorkomt. {3} betekent precies drie keer het voorafgaande onderdeel. Het voorbeeldpatroon hieronder vraagt daardoor drie hoofdletters, een dubbele punt en twee cijfers.
| Patroononderdeel | Wat het vraagt |
|---|---|
[A-Z] | Eén gewone hoofdletter |
{3} | Precies drie keer het vorige onderdeel |
: | Letterlijk een dubbele punt |
[0-9]{2} | Precies twee ASCII-cijfers |
fullmatch probeert de volledige string op het patroon te laten passen. Bij succes krijg je een matchobject terug: een waarde die de gevonden overeenkomst beschrijft. Bij mislukking krijg je None.
Met is not None zet je dat resultaat om in de boolean die je functie moet teruggeven. Geef dus niet het matchobject zelf terug. De toetsen onderscheiden een boolean van andere waarden die in een if misschien ook als waar tellen.
Een r vóór de patroonstring maakt een raw string, waarin backslashes niet zoals gewone Python-escapes worden verwerkt. Voor het eenvoudige voorbeeld is dat verschil niet zichtbaar. Deze schrijfwijze houdt regexcode duidelijk wanneer je later wel patroononderdelen met backslashes gebruikt.
Voorspel welke labels precies passen en voer het volledige voorbeeld uit. De extra letter en het regeleinde horen ook bij de invoer.
import re
pattern = r"[A-Z]{3}:[0-9]{2}"
for label in ["PAD:07", "PAD:07X", "PAD:07\n"]:
print(re.fullmatch(pattern, label) is not None)True False False
match controleert vanaf het begin, maar hoeft niet de hele tekst te gebruiken. Een geldig begin met rommel erachter kan daardoor toch een match opleveren. De foutvariant laat dat verschil zien.
import re
print(re.match(r"[A-Z]{3}:[0-9]{2}", "PAD:07X") is not None)True
Het programma meldt waar, terwijl de laatste letter niet bij het label hoort. fullmatch zou die extra invoer afwijzen. Ook afsluitende spaties en regeleinden moeten worden meegenomen wanneer je een exact formaat controleert.
Schrijf valid_code voor twee gewone hoofdletters, één koppelteken en precies drie ASCII-cijfers. Alle vier stappen controleren dezelfde functie, telkens met andere kanten van dit contract. Zo zie je of een fout in de basisvorm, lengte, tekens of volledige overeenkomst zit.
Verwijder geen spaties en maak de tekst niet automatisch groter. De aangeleverde string moet zelf passen. Een lege string en elk extra teken worden afgewezen.
Laat valid_code een boolean teruggeven voor twee gewone hoofdletters, één koppelteken en drie ASCII-cijfers.
Laat valid_code afwijkende aantallen letters of cijfers afwijzen, ook als het begin op een goede code lijkt.
Laat valid_code kleine letters, letters buiten A tot en met Z en niet-ASCII-cijfers afwijzen. Verander de invoer niet vooraf.
Laat valid_code extra tekst, spaties en een afsluitend regeleinde afwijzen. Alleen de complete string mag passen.
fullmatch gebruikt de hele invoer en geeft een matchobject of None terug.Hierna combineer je de tekstbewerkingen in een kleine parser.
Voer je code uit en ontdek
wat je hebt gemaakt.
Je hoeft het niet in één keer goed te doen. Na het uitvoeren zie je hier welke stappen al kloppen.