★ Dev formats · regex
Regex for Semantic Version
The regex published by semver.org for SemVer 2.0.0. It captures major, minor, patch, pre-release and build metadata, and rejects leading zeros in numeric parts.
- Runs in your browser
- No signup
Try the semantic version pattern
Read it in plain English (best-effort)
- ^start of a line
- (start capture group 1
- 0the character '0'
- |or
- [1-9]one character from: 1–9
- \da digit (0–9)
- *zero or more of the previous
- )end of group
- .the character '.'
- (start capture group 2
- 0the character '0'
- |or
- [1-9]one character from: 1–9
- \da digit (0–9)
- *zero or more of the previous
- )end of group
- .the character '.'
- (start capture group 3
- 0the character '0'
- |or
- [1-9]one character from: 1–9
- \da digit (0–9)
- *zero or more of the previous
- )end of group
- (?:start a group (not captured)
- -the character '-'
- (start capture group 4
- (?:start a group (not captured)
- 0the character '0'
- |or
- [1-9]one character from: 1–9
- \da digit (0–9)
- *zero or more of the previous
- |or
- \da digit (0–9)
- *zero or more of the previous
- [a-zA-Z-]one character from: a–z, A–Z, '-'
- [0-9a-zA-Z-]one character from: 0–9, a–z, A–Z, '-'
- *zero or more of the previous
- )end of group
- (?:start a group (not captured)
- .the character '.'
- (?:start a group (not captured)
- 0the character '0'
- |or
- [1-9]one character from: 1–9
- \da digit (0–9)
- *zero or more of the previous
- |or
- \da digit (0–9)
- *zero or more of the previous
- [a-zA-Z-]one character from: a–z, A–Z, '-'
- [0-9a-zA-Z-]one character from: 0–9, a–z, A–Z, '-'
- *zero or more of the previous
- )end of group
- )end of group
- *zero or more of the previous
- )end of group
- )end of group
- ?the previous is optional
- +15 more
One sample per line works well with the m flag on anchored patterns.
The pattern, piece by piece
/^(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-]+)*))?$/| Part | What it does |
|---|---|
(0|[1-9]\d*) | groups 1–3: major, minor, patch, with no leading zeros |
(?:-(…))? | group 4: optional pre-release like alpha.1 |
(?:\+(…))? | group 5: optional build metadata like +exp.sha.5114f85 |
What it accepts and rejects
Every sample below is checked automatically in JavaScript and Python. The tester above is preloaded with all of them, one per line.
| Should match | |
|---|---|
1.0.0 | ✓ |
0.1.0 | ✓ |
2.10.3 | ✓ |
1.0.0-alpha | ✓ |
1.0.0-alpha.1 | ✓ |
1.0.0+20130313144700 | ✓ |
1.0.0-beta+exp.sha.5114f85 | ✓ |
| Should not match | |
|---|---|
1 | ✗ |
1.0 | ✗ |
01.0.0 | ✗ |
1.0.0- | ✗ |
1.0.0-01 | ✗ |
v1.0.0 | ✗ |
1.0.0+ | ✗ |
Copy it into your code
RE2-safeNo lookarounds or backreferences, so the same pattern works in Go's RE2 engine and in Rust's regex crate.
const semverRe = /^(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-]+)*))?$/;
export function isValidSemver(value) {
return semverRe.test(value.trim());
}When not to use regex for this
To compare or sort versions, use a semver library (semver on npm, golang.org/x/mod/semver). Precedence rules for pre-releases are subtle.
Questions engineers actually ask
Why doesn't v1.0.0 match?
Is 1.0.0-01 valid?
What is catastrophic backtracking?
Sources
Formats were checked on 8 November 2026. Rules change; the official issuer wins if it disagrees.
More dev formats patterns
- UUIDRFC 9562 UUIDs, versions 1–8, with the standard variant bits.^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$
- ISO 8601 DateYYYY-MM-DD dates with valid month and day ranges. Format only.^\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])$
- 24-hour TimeHH:MM or HH:MM:SS in 24-hour format, 00:00 to 23:59:59.^(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d)?$
- JWTThree base64url segments starting with eyJ. Shape only, never trust it.^eyJ[A-Za-z0-9_-]*\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]*$
- Base64Standard padded base64: groups of four with = or == padding.^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$
- MAC AddressColon, hyphen or Cisco dot notation, without mixing separators.^(?:(?:[0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}|(?:[0-9A-Fa-f]{2}-){5}[0-9A-Fa-f]{2}|(?:[0-9A-Fa-f]{4}\.){2}[0-9A-Fa-f]{4})$
Or browse the full regex library.
More from the workbench
Fine print
Tools: on the house.
Engineer: by the hour.
The regex was free. Code that doesn't need one is the upgrade: typed schemas, validated once at the edge, trusted everywhere after.
I'm Himanshu, an AI and full-stack engineer. I build MVPs, AI agents and the growth plumbing around them for early-stage startups.
