Regex SemVer version number
The most copied SemVer regex (a GitHub gist with 60+ stars) accepts "0001.0001.0001", which is invalid per spec. Two community fixes partially solved the problem without fully fixing it. Here's the pattern officially recommended by semver.org, compared against the three real steps of that fix.
/^(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-]+)*))?$/passes 20/20 cases
Comparison of existing patterns
| Source | pattern | Score on the 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 | safe |
| 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 | safe |
| 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 | safe |
Implementation
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);Limits
- 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.