RRegexBuilder
Get RegexBuilder

RegexBuilder · regex answers

Regex for a semantic version

/^(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-]+)*))?$/

This is the pattern published in the SemVer 2.0.0 specification itself. Each numeric identifier rejects leading zeros, pre-release identifiers are dot-separated, and build metadata after the plus sign is ignored when versions are compared.

What each part does

(0|[1-9]\d*)major, minor and patch — no leading zeros
(?:- … )?the optional pre-release, after a hyphen
(?:\+ … )?the optional build metadata, after a plus

Tested against real input

Every row below was run through the engine when this page was built. The third column is the substring the pattern actually matched.

InputResultMatched
1.0.0matches1.0.0
0.1.2matches0.1.2
1.0.0-alpha.1matches1.0.0-alpha.1
1.0.0-rc.1+build.5matches1.0.0-rc.1+build.5
1.0no match
01.0.0no match
1.0.0-no match
v1.0.0no match

The mistake to avoid

Accepting a leading v. Tags are often written v1.0.0 but the version itself is not — strip the prefix before you test.

Try it on your own text

Paste this pattern and your input, see each match highlighted with its capture groups, step through what the engine did, and get the equivalent syntax for JavaScript, Python, Java, Go and PCRE.

Open RegexBuilder

Other regex answers