Regex numéro de version SemVer
Le regex SemVer le plus copié (un gist GitHub à plus de 60 étoiles) accepte « 0001.0001.0001 », pourtant invalide selon la spec. Deux corrections communautaires ont partiellement résolu le problème sans le corriger entièrement. Voici le motif officiellement recommandé par semver.org, comparé aux trois étapes réelles de cette correction.
/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/passe 20/20 cas
Comparatif des patterns existants
| Source | pattern | Score sur le corpus | ReDoS |
|---|---|---|---|
| GitHub Gist — version originale, 60+ étoiles (jhorsman) | ^([0-9]+)\.([0-9]+)\.([0-9]+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+)?$ | 15 / 20 | sûr |
| GitHub Gist — correctif communautaire n°1 (bartelsielski), zéros non significatifs de major/minor/patch corrigés | ^([0-9]|[1-9][0-9]*)\.([0-9]|[1-9][0-9]*)\.([0-9]|[1-9][0-9]*)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+)?$ | 18 / 20 | sûr |
| GitHub Gist — correctif communautaire n°2 (almic), métadonnées de build à plusieurs identifiants supportées | ^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(-[a-zA-Z\d][-a-zA-Z.\d]*)?(\+[a-zA-Z\d][-a-zA-Z.\d]*)?$ | 19 / 20 | sûr |
Implémentation
const re = new RegExp("^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$", "");
re.test(input);Limites
- Valide seulement la forme : ne vérifie pas qu'une version « supérieure » selon SemVer (ex. comparer 1.2.0 à 1.10.0) est bien plus récente — ça demande de parser les nombres, pas juste de matcher une chaîne.
- N'accepte pas le préfixe « v » parfois utilisé avec les tags Git (ex. « v1.2.3 ») — c'est volontaire : ce préfixe n'appartient pas au numéro de version selon la spec, il faut le retirer avant validation.
- Ne garantit pas que l'auteur du paquet respecte réellement les règles sémantiques de SemVer (incrémenter MAJOR pour un changement cassant, etc.) — la regex valide un format, pas une intention.
- Les groupes capturants diffèrent d'une implémentation à l'autre pour la pré-release et les métadonnées de build : vérifie toujours lesquels correspondent à quoi avant de les réutiliser.