Regex plaque d'immatriculation polonaise
Une plaque polonaise de voiture commence par 2 ou 3 lettres de voïvodie et de powiat (« DW », « DBL »), puis une partie véhicule dont la forme dépend de la longueur du préfixe. Le règlement du 8 novembre 2024 (Dz.U. 2024 poz. 1709, § 31) exclut les lettres B, D, I, O et Z de cette partie, et interdit les numéros nuls (« 00000 », « 0A345 »). Les tentatives réelles s'en tiennent à des classes larges : « DW 1B345 » et « DW 00000 » passent presque partout, et le gem Ruby exclut I, O et U au lieu de B, D, I, O et Z. Voici un motif qui suit les tableaux du règlement, comparé à ces tentatives.
/^(?:[A-PR-Z]{2} (?:(?!0{5})[0-9]{5}|(?!0{4})[0-9]{4}[ACE-HJ-NPR-Y]|(?!0{3})[0-9]{3}[ACE-HJ-NPR-Y]{2}|[1-9][ACE-HJ-NPR-Y](?!0{3})[0-9]{3}|[1-9][ACE-HJ-NPR-Y]{2}(?!00)[0-9]{2})|[A-PR-Z]{3} (?:[ACE-HJ-NPR-Y](?!0{3})[0-9]{3}|(?!00)[0-9]{2}[ACE-HJ-NPR-Y]{2}|[1-9][ACE-HJ-NPR-Y](?!00)[0-9]{2}|(?!00)[0-9]{2}[ACE-HJ-NPR-Y][1-9]|[1-9][ACE-HJ-NPR-Y]{2}[1-9]|[ACE-HJ-NPR-Y]{2}(?!00)[0-9]{2}|(?!0{5})[0-9]{5}|(?!0{4})[0-9]{4}[ACE-HJ-NPR-Y]|(?!0{3})[0-9]{3}[ACE-HJ-NPR-Y]{2}))$/passe 33/33 cas
Comparatif des patterns existants
| Source | pattern | Score sur le corpus | ReDoS |
|---|---|---|---|
| ariejan/license_plate_validator (gem Ruby, 38 regex réunies par |) — la classe « [A-HJ-NP-TV-Z] » exclut I, O et U au lieu de B, D, I, O, Z : « DW 1B345 » et « DW 1234Z » passent ; zéros initiaux acceptés ; préfixe [A-Z]{2} accepte Q | ^([A-Z]{2})\s([0-9]{5})$|^([A-Z]{2})\s([0-9]{4}[A-HJ-NP-TV-Z])$|^([A-Z]{2})\s([0-9]{3}[A-HJ-NP-TV-Z]{2})$|^([A-Z]{2})\s([0-9][A-HJ-NP-TV-Z][0-9]{3})$|^([A-Z]{2})\s([0-9][A-HJ-NP-TV-Z]{2}[0-9]{2})$|^([A-Z]{3})\s([A-HJ-NP-TV-Z][0-9]{3})$|^([A-Z]{3})\s([0-9]{2}[A-HJ-NP-TV-Z]{2})$|^([A-Z]{3})\s([0-9][A-HJ-NP-TV-Z][0-9]{2})$|^([A-Z]{3})\s([0-9]{2}[A-HJ-NP-TV-Z][0-9])$|^([A-Z]{3})\s([0-9][A-HJ-NP-TV-Z]{2}[0-9])$|^([A-Z]{3})\s([A-HJ-NP-TV-Z]{2}[0-9]{2})$|^([A-Z]{3})\s([0-9]{5})$|^([A-Z]{3})\s([0-9]{4}[A-HJ-NP-TV-Z])$|^([A-Z]{3})\s([0-9]{3}[A-HJ-NP-TV-Z]{2})$|^([A-Z]{2})\s([0-9]{4})$|^([A-Z]{2})\s([0-9]{3}[A-HJ-NP-TV-Z])$|^([A-Z]{2})\s([0-9][A-HJ-NP-TV-Z][0-9]{2})$|^([A-Z]{2})\s([0-9]{2}[A-HJ-NP-TV-Z][0-9])$|^([A-Z]{2})\s([0-9]{2}[A-HJ-NP-TV-Z]{2})$|^([A-Z]{2})\s([A-HJ-NP-TV-Z]{2}[0-9]{2})$|^([A-Z])\s([0-9]{3})$|^([A-Z])\s([0-9]{2}[A-HJ-NP-TV-Z])$|^([A-Z])\s([0-9][A-HJ-NP-TV-Z][0-9])$|^([A-Z])\s([A-HJ-NP-TV-Z][0-9]{2})$|^([A-Z])\s([0-9][A-HJ-NP-TV-Z]{2})$|^([A-Z])\s([A-HJ-NP-TV-Z]{2}[0-9])$|^([A-Z])\s([A-HJ-NP-TV-Z][0-9][A-HJ-NP-TV-Z])$|^([A-Z]{2})\s([0-9]{2}[A-HJ-NP-TV-Z])$|^([A-Z]{2})\s([0-9]{3})$|^([A-Z]{3})\s([0-9][A-HJ-NP-TV-Z])$|^([A-Z]{3})\s([0-9]{2})$|^([A-Z]{3})\s([A-HJ-NP-TV-Z][0-9])$|^([A-Z][0-9])\s([0-9]{4})$|^([A-Z][0-9])\s([0-9]{3}[A-HJ-NP-TV-Z])$|^([A-Z][0-9])\s([0-9]{3})\sB$|^([A-Z][0-9])\s([A-Z][A-Z]{2,4})$|^([A-Z][0-9])\s([A-Z][A-Z]{1,3}[0-9]{1,2})$|^([A-Z][0-9]{2})\s([0-9]{2}P[0-9]{2})$ | 25 / 33 | sûr |
| @randock/license-plate-validator (npm, deux regex réunies par | ; l'entrée est d'abord normalisée) — exclut bien B, D, I, O, Z, mais « {2,5} » laisse passer n'importe quelle longueur et mélange : « DW 123456 », « DW 12AC3 », « DW 00000 » passent | ^([A-PR-Z]{2})([0-9][ACE-HJ-NPR-Y0-9]{2,5})$|^([A-PR-Z]{3})([ACE-HJ-NPR-Y0-9]{2,5})$ | 19 / 33 | sûr |
| CodeCornTech (euro-plate-validator) — une seule regex très large : accepte B, D, I, O, Z, « DW 00000 » et « DW 12AC3 » | ^[A-Z]{1,3}\s?[A-Z0-9]{4,5}$ | 21 / 33 | sûr |
Implémentation
const re = new RegExp("^(?:[A-PR-Z]{2} (?:(?!0{5})[0-9]{5}|(?!0{4})[0-9]{4}[ACE-HJ-NPR-Y]|(?!0{3})[0-9]{3}[ACE-HJ-NPR-Y]{2}|[1-9][ACE-HJ-NPR-Y](?!0{3})[0-9]{3}|[1-9][ACE-HJ-NPR-Y]{2}(?!00)[0-9]{2})|[A-PR-Z]{3} (?:[ACE-HJ-NPR-Y](?!0{3})[0-9]{3}|(?!00)[0-9]{2}[ACE-HJ-NPR-Y]{2}|[1-9][ACE-HJ-NPR-Y](?!00)[0-9]{2}|(?!00)[0-9]{2}[ACE-HJ-NPR-Y][1-9]|[1-9][ACE-HJ-NPR-Y]{2}[1-9]|[ACE-HJ-NPR-Y]{2}(?!00)[0-9]{2}|(?!0{5})[0-9]{5}|(?!0{4})[0-9]{4}[ACE-HJ-NPR-Y]|(?!0{3})[0-9]{3}[ACE-HJ-NPR-Y]{2}))$", "");
re.test(input);Limites
- Valide seulement la FORME : ne connaît pas la liste des powiats de l'annexe 13 du règlement. « XX 12345 » a la bonne forme sans qu'aucun powiat « XX » n'existe ; seule une table de préfixes, que ce motif ne reprend pas, le détecterait.
- Ne couvre que les plaques standard de voiture (§ 30 ust. 2 pkt 1). Les plaques individuelles (« D1 ABC », « D2 WXY12 »), de moto, de taille réduite, d'essai, d'exportation et diplomatiques suivent d'autres tableaux et sont rejetées.
- Le règlement distingue les préfixes à 2 lettres (powiat à lettre unique) et à 3 lettres, chacun avec ses tableaux de partie véhicule ; une regex ne peut pas savoir si « DW » est un préfixe à 2 lettres ou le début d'un préfixe à 3 lettres sans la liste des powiats. Le motif accepte les deux familles de formes pour tout préfixe de la bonne longueur.
- Basé sur le règlement du 8 novembre 2024 (Dz.U. 2024 poz. 1709) ; les modifications de 2025 et 2026 n'ont pas été relues et pourraient changer les tableaux.
Plaques d’immatriculation d’autres pays
- plaque d'immatriculation allemande
- plaque d'immatriculation belge
- plaque d'immatriculation britannique (format actuel)
- plaque d'immatriculation espagnole (format actuel)
- plaque d'immatriculation italienne
- plaque d'immatriculation néerlandaise (kenteken)
- plaque d'immatriculation portugaise
- plaque d'immatriculation SIV
- Toutes les plaques d’immatriculation par pays