Voordat je regular expressions gaat schrijven, moet je eerst bedenken wat een domeinnaam is. Het komt er op neer dat een domeinnaam bestaat uit een aantal labels, gescheiden door punten. Als je een expressie X hebt voor een label, dan is een reguliere expressie voor de domeinnaam dus
^X(\.X)*$. Nu is een enkel label ook een geldige domeinnaam, als je er minstens één punt in wil hebben kun je
^X(\.X)+ schrijven.
Nu is het de vraag: wat is X precies? Een label bestaat uit letters, cijfers en streepjes, maar mag niet met een streepje beginnen of eindigen ("a--z.com" is dus daadwerkelijk een geldig domein). Sommige TLD's hebben nog extra eisen, zoals dat in Nederland een label niet uit alleen cijfers mag bestaan, maar daar kun je in het algemeen niet van uitgaan. Je begint dus met een letter of cijfer, dan optioneel letters, cijfers en streepjes en weer een letter of cijfer:
[A-Za-z0-9]([-A-Za-z0-9]*[A-Za-z0-9])?. Merk op dat het noodzakelijk is om ook het laatste karakter optioneel te maken, omdat je ook labels met maar één letter hebt ("x.org", bijvoorbeeld).
Nu kun je die expressie invoegen in de eerdere expresssie en dan krijg je dus:
^[A-Za-z0-9]([-A-Za-z0-9]*[A-Za-z0-9])?(\.[A-Za-z0-9]([-A-Za-z0-9]*[A-Za-z0-9])?)*$
Dat is nogal lang en lastig te lezen en dat is ook een probleem met reguliere expressies: als je weet waar je mee bezig bent kun je ze goed construeren, maar ze zijn lastig te lezen en te onderhouden.
Je kunt het wel iets makkelijker maken door zelf eerst een punt voor de domeinnaam te zetten; de reguliere expressie wordt dan namelijk
^(.X)+$ en volledig ingevuld:
^(\.[A-Za-z0-9]([-A-Za-z0-9]*[A-Za-z0-9])?)*$. Dat is al een stuk korter en je voorkomt de duplicatie van code enigzins. Ook kun je, als je POSIX of Perl expressies gebruikt, de character classes korter opschrijven.
Nu accepteer je trouwens ook domeinnamen als "abc.xyv", wat waarschijnlijk niet bestaat, maar dat kun je toch nooit controleren zonder een DNS lookup te doen.
[
Voor 43% gewijzigd door
Soultaker op 16-09-2005 17:02
]