Rexact
Cheatsheet

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

SourcepatternScore on the corpusReDoS
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 / 20safe
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 / 20safe
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 / 20safe

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.