Regex Dutch licence plate (kenteken)
The Rijksdienst voor het Wegverkeer (RDW) defines 14 plate series, from XX-99-99 (1951) to XXX-99-X (2024). Since series 4, vowels, C and Q are no longer used, and combinations like SS, SD, NSB, PVV or BBB are excluded. Almost every real attempt ignores this: a Ruby gem accepts any letters and a Go module knows only three formats out of fourteen, rejecting for example GH-12-JK (the trailer series). Here's a pattern covering the 14 series, with modern plate letters and the list of excluded combinations, compared against those three real attempts.
/^(?:[A-Z]{2}-[0-9]{2}-[0-9]{2}|[0-9]{2}-[0-9]{2}-[A-Z]{2}|[0-9]{2}-[A-Z]{2}-[0-9]{2}|(?!.*(?:GVD|KKK|NSB|PKK|PSV|TBS|PVV|SGP|VVD|FVD|BBB|SS|SD))(?:[BDFGHJKLMNPRSTVWXZ]{2}-[0-9]{2}-[BDFGHJKLMNPRSTVWXZ]{2}|[BDFGHJKLMNPRSTVWXZ]{2}-[BDFGHJKLMNPRSTVWXZ]{2}-[0-9]{2}|[0-9]{2}-[BDFGHJKLMNPRSTVWXZ]{2}-[BDFGHJKLMNPRSTVWXZ]{2}|[0-9]{2}-[BDFGHJKLMNPRSTVWXZ]{3}-[0-9]|[0-9]-[BDFGHJKLMNPRSTVWXZ]{3}-[0-9]{2}|[BDFGHJKLMNPRSTVWXZ]{2}-[0-9]{3}-[BDFGHJKLMNPRSTVWXZ]|[BDFGHJKLMNPRSTVWXZ]-[0-9]{3}-[BDFGHJKLMNPRSTVWXZ]{2}|[BDFGHJKLMNPRSTVWXZ]{3}-[0-9]{2}-[BDFGHJKLMNPRSTVWXZ]|[BDFGHJKLMNPRSTVWXZ]-[0-9]{2}-[BDFGHJKLMNPRSTVWXZ]{3}|[0-9]-[BDFGHJKLMNPRSTVWXZ]{2}-[0-9]{3}|[0-9]{3}-[BDFGHJKLMNPRSTVWXZ]{2}-[0-9]))$/passes 33/33 cases
Comparison of existing patterns
| Source | pattern | Score on the corpus | ReDoS |
|---|---|---|---|
| ariejan/license_plate_validator (gem Ruby) — 14 formats mais « [a-zA-Z] » partout : voyelles, C, Q et combinaisons interdites (SS, NSB, PVV, BBB) passent ; tirets facultatifs | ^([a-zA-Z]{2})-?([0-9]{2})-?([0-9]{2})$|^([0-9]{2})-?([0-9]{2})-?([a-zA-Z]{2})$|^([0-9]{2})-?([a-zA-Z]{2})-?([0-9]{2})$|^([a-zA-Z]{2})-?([0-9]{2})-?([a-zA-Z]{2})$|^([a-zA-Z]{2})-?([a-zA-Z]{2})-?([0-9]{2})$|^([0-9]{2})-?([a-zA-Z]{2})-?([a-zA-Z]{2})$|^([0-9]{2})-?([a-zA-Z]{3})-?([0-9]{1})$|^([0-9]{1})-?([a-zA-Z]{3})-?([0-9]{2})$|^([a-zA-Z]{2})-?([0-9]{3})-?([a-zA-Z]{1})$|^([a-zA-Z]{1})-?([0-9]{3})-?([a-zA-Z]{2})$|^([a-zA-Z]{3})-?([0-9]{2})-?([a-zA-Z])$|^([0-9]{3})-?([a-zA-Z]{2})-?([0-9])$|^([a-zA-Z])-?([0-9]{2})-?([a-zA-Z]{3})$|^([0-9])-?([a-zA-Z]{2})-?([0-9]{3})$ | 25 / 33 | safe |
| eu-licence-validator (Go, WASM) — trois formats seulement : rejette GH-12-JK (série 4), BD-JK-12 (série 5), 5-KLN-67 (série 8), GH-123-J (série 9)… | ^([A-Z]{2})[-\s]?(\d{2})[-\s]?(\d{2})$|^(\d{2})[-\s]?([A-Z]{2})[-\s]?(\d{2})$|^(\d{1,2})[-\s]?([A-Z]{3})[-\s]?(\d)$ | 21 / 33 | safe |
| CodeCornTech (euro-plate-validator, neuf regex réunies par |) — lettres sans M ni W mais avec Y : la plaque de remorque WB-12-DF est rejetée ; ni XX-99-XX ni 99-99-XX ; combinaisons interdites non contrôlées | ^[BDFGHJKLNPRSTVXYZ]{2}-\d{3}-[BDFGHJKLNPRSTVXYZ]{2}$|^\d{2}-[BDFGHJKLNPRSTVXYZ]{3}-\d$|^\d-[BDFGHJKLNPRSTVXYZ]{3}-\d{2}$|^[BDFGHJKLNPRSTVXYZ]{2}-[BDFGHJKLNPRSTVXYZ]{2}-\d{2}$|^\d{2}-[BDFGHJKLNPRSTVXYZ]{2}-[BDFGHJKLNPRSTVXYZ]{2}$|^[BDFGHJKLNPRSTVXYZ]{3}-\d{2}-[BDFGHJKLNPRSTVXYZ]$|^[BDFGHJKLNPRSTVXYZ]-\d{3}-[BDFGHJKLNPRSTVXYZ]{2}$|^[BDFGHJKLNPRSTVXYZ]{2}-\d{3}-[BDFGHJKLNPRSTVXYZ]$|^\d-[BDFGHJKLNPRSTVXYZ]{2}-\d{3}$ | 22 / 33 | safe |
Implementation
const re = new RegExp("^(?:[A-Z]{2}-[0-9]{2}-[0-9]{2}|[0-9]{2}-[0-9]{2}-[A-Z]{2}|[0-9]{2}-[A-Z]{2}-[0-9]{2}|(?!.*(?:GVD|KKK|NSB|PKK|PSV|TBS|PVV|SGP|VVD|FVD|BBB|SS|SD))(?:[BDFGHJKLMNPRSTVWXZ]{2}-[0-9]{2}-[BDFGHJKLMNPRSTVWXZ]{2}|[BDFGHJKLMNPRSTVWXZ]{2}-[BDFGHJKLMNPRSTVWXZ]{2}-[0-9]{2}|[0-9]{2}-[BDFGHJKLMNPRSTVWXZ]{2}-[BDFGHJKLMNPRSTVWXZ]{2}|[0-9]{2}-[BDFGHJKLMNPRSTVWXZ]{3}-[0-9]|[0-9]-[BDFGHJKLMNPRSTVWXZ]{3}-[0-9]{2}|[BDFGHJKLMNPRSTVWXZ]{2}-[0-9]{3}-[BDFGHJKLMNPRSTVWXZ]|[BDFGHJKLMNPRSTVWXZ]-[0-9]{3}-[BDFGHJKLMNPRSTVWXZ]{2}|[BDFGHJKLMNPRSTVWXZ]{3}-[0-9]{2}-[BDFGHJKLMNPRSTVWXZ]|[BDFGHJKLMNPRSTVWXZ]-[0-9]{2}-[BDFGHJKLMNPRSTVWXZ]{3}|[0-9]-[BDFGHJKLMNPRSTVWXZ]{2}-[0-9]{3}|[0-9]{3}-[BDFGHJKLMNPRSTVWXZ]{2}-[0-9]))$", "");
re.test(input);Limits
- Valide seulement la FORME : ne vérifie pas que la plaque est attribuée par le RDW. Les séries 1 à 3 (1951 à 1988) acceptent toutes les lettres, y compris les voyelles, ce qui est historiquement correct mais laisse passer « SS-12-34 » (la liste des combinaisons exclues n'est appliquée qu'aux séries 4 et suivantes, faute de source sur leur application aux anciennes plaques).
- Les lettres autorisées (sans voyelles, C, Q ni Y) valent pour toutes les séries modernes : le RDW précise des premières lettres par catégorie de véhicule (M pour les motos, V pour les utilitaires légers, B pour les poids lourds, W pour les remorques…) que ce motif n'encode pas. Le statut de la lettre Y n'a pas pu être confirmé auprès du RDW.
- Exige les tirets, comme les plaques officielles : « GH12JK » est rejeté. Les séries spéciales (BN, GN, CD, CDJ, GV) ne sont pas couvertes.
- Les dates de chaque série viennent de la page du RDW consultée ; elle a pu être mise à jour depuis. Majuscules ASCII seulement : « gh-12-jk » est rejeté.