Skip to content

Semantic Version (SemVer) Regex

Validate semantic version numbers with the official SemVer 2.0.0 pattern: major, minor and patch, an optional pre-release and optional build metadata.

JavaScript
142 characters

One case per line; the m flag makes ^ and the end anchor work line by line.

Link optionspattern only

The address bar holds the pattern, flags and replacement, so Copy link shares them. Your test text stays out of it unless you include it (up to 2,000 characters), because it may be private. Nothing is sent to a server.

Matches

7matches

The first is “1.0.0”, at position 0.

Groups
1, 2, 3, 4, 5
Characters matched
94 of 142
What the pattern meansHover or tap a part to see it in the pattern and what it matched
How this works: Method, 4 sources, Checked against 1 worked example,

How this works

Method

Your pattern runs in your own browser’s JavaScript engine, in a background worker that is stopped after 1.5 seconds, so a pattern that backtracks catastrophically can’t freeze the page. The explanation comes from our own parser of the ECMAScript pattern grammar, checked against the engine; what each part matched is found by wrapping that part in one more group and running the pattern again. Conversions to other flavours only rewrite the syntax and list what their documentation says works differently.

How it’s tested

One worked example for this page is checked by automated tests before every release: given the inputs, the tool must show the expected answer.

Changes

  • First published, with a library of 19 common patterns and their test cases.

How we make toolsReport a mistake

Worked example

Take 1.0.0, the first case in the tester. Reading the pattern left to right, each part takes its share of the text:

  1. ^The start of the text (matches a position, no characters)
  2. (0|[1-9]\d*)Group 1, either of two alternatives: matches 1
  3. \.“.” matches .
  4. (0|[1-9]\d*)Group 2, either of two alternatives: matches 0
  5. \.“.” matches .
  6. (0|[1-9]\d*)Group 3, either of two alternatives: matches 0
  7. (?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?A group (not captured), optional (zero or one time): (matches a position, no characters)
  8. (?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?A group (not captured), optional (zero or one time): (matches a position, no characters)
  9. $The end of the text (matches a position, no characters)

How the SemVer regex works

This is the suggested regex with numbered capture groups published on semver.org, unchanged. Its first three groups read the major, minor and patch numbers with (0|[1-9]\d*): either a lone zero or a number that does not start with zero. That one rule rejects 01.0.0.

The optional pre-release starts with a hyphen and is captured as group 4. Each dot-separated identifier is either a number without leading zeros or \d*[a-zA-Z-][0-9a-zA-Z-]*, an alphanumeric identifier that contains at least one letter or hyphen. So 0.3.7 and alpha.1 pass, while 01 fails, because an all-digit identifier must follow the number rule.

Build metadata after a plus sign is group 5: one or more dot-separated runs of letters, digits and hyphens, where leading zeros are allowed. Because the groups are numbered, a match gives you each part directly, ready to compare.

  • Semantic Versioning 2.0.0 says numeric identifiers must not include leading zeroes, which is why 01.0.0 and 1.0.0-01 fail. Source: Semantic Versioning 2.0.0.
  • Build metadata must be ignored when determining version precedence, so 1.0.0+build.1 and 1.0.0+build.2 rank the same. Source: Semantic Versioning 2.0.0.

Test cases

Every case runs as an automated test of this page’s pattern, so the table can’t drift from what the pattern really does.

Test cases for the Semantic version regex
TextResultWhy
1.0.0Passesa plain release
0.1.0Passesmajor version zero, still in development
1.0.0-alpha.1Passesa pre-release with a numeric part
1.0.0-0.3.7Passesa pre-release made of numbers
1.0.0-x.7.z.92Passesmixed pre-release identifiers
1.0.0+20130313144700Passesbuild metadata only
1.0.0-beta+exp.sha.5114f85Passespre-release and build metadata
1.0Failsthe patch number is missing
01.0.0Failsa leading zero in the major version
v1.0.0Failsa v prefix is a tag convention, not part of the version
1.0.0-01Failsa numeric pre-release identifier with a leading zero
1.0.0-Failsan empty pre-release
1.2.3.4Failsa fourth number

What it doesn’t check

  • Many tools write tags as v1.2.3; strip the v before testing, since the specification does not include it.
  • The regex validates one version, not a range: npm-style ranges such as ^1.2.0 or >=1.0.0 need a range parser.
  • Comparing versions needs more than the regex: pre-release identifiers compare part by part, numbers numerically and text by ASCII order.

The same pattern in other languages

Converted automatically from the JavaScript version; the tester above always runs JavaScript.

The pattern in Python, PCRE, Go, Java and .NET
FlavourPatternNotes
Python(?a)^(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\-]+)*))?\Z
PCRE^(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\-]+)*))?\z
Go^(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\-]+)*))?$The pattern uses no lookarounds or backreferences, so it runs unchanged in Go’s RE2 engine.
Java^(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\-]+)*))?\z
.NET^(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\-]+)*))?\zIn .NET, \d and \w match any Unicode digit or letter. Pass RegexOptions.ECMAScript, or write [0-9] and [A-Za-z0-9_], for JavaScript’s ASCII-only meaning.

Sources

Frequently Asked Questions

Is there an official regex for semantic versioning?

Yes. The SemVer 2.0.0 specification suggests two: one with named groups and one with numbered groups for engines that lack named groups. This page uses the numbered version as published.

How do I allow a leading v, as in v2.1.0?

Add an optional v after the start anchor. Keep it out of the captured groups, so the major version is still group 1.

Can I compare two versions with this regex?

It extracts the parts, but you still compare them in code: major, then minor, then patch as numbers, and a version with a pre-release ranks below the same version without one.