Skip to content
shellhacks.dev
Regular Expressions

Match a semantic version

Match a semantic version with the pattern from semver.org, which runs in grep -E. It rejects leading zeros, a bare 1.2 and a v prefix, and takes pre-release tags.

1 min read
Summarize in AI

A version string has to be checked before it is compared, and a loose pattern like three numbers with dots accepts values the specification forbids.

Shell
re='^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-((0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*))*))?(\+([0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*))?$'
for v in 1.2.3 1.2.3-rc.1+build.5 01.2.3 1.2 v1.2.3 1.2.3-01 1.2.3-alpha-1; do
  if printf '%s\n' "$v" | grep -qE "$re"; then echo "valid:   $v"; else echo "invalid: $v"; fi
done
Text
valid:   1.2.3
valid:   1.2.3-rc.1+build.5
invalid: 01.2.3
invalid: 1.2
invalid: v1.2.3
invalid: 1.2.3-01
valid:   1.2.3-alpha-1

The semantic versioning specification publishes one regular expression, and the version above is that pattern without the named groups, so it works in extended regular expressions. Each number is 0 or starts with a digit other than zero, which rules out 01.2.3. The optional hyphen part holds pre-release identifiers, where a numeric identifier cannot have a leading zero, so 1.2.3-01 fails, and the plus part holds build metadata.

A leading v, common in Git tags, is not part of a semantic version, so strip it first with ${tag#v}. The pattern says whether a string is valid and not which of two versions is newer; sort -V orders many versions, but does not follow the precedence rules for pre-releases exactly. In Python or JavaScript, the capture groups give the parts.

Taggedregextext
Share

More snippets

Regular Expressions

Match a quoted string

Match a quoted string with a negated character class. An escaped quote inside the text ends the match early, and a PCRE alternation that pairs backslashes handles it.

1 min read
Regular Expressions

Match an ISO date

Match an ISO date with [0-9]{4}-[0-9]{2}-[0-9]{2}. The pattern checks the shape only, and a tighter month and day range still accepts February 31.

2 min read
Regular Expressions

Match a UUID

Match a version 4 UUID with 8-4-4-4-12 hex groups, a 4 at the start of the third group and 8, 9, a or b at the start of the fourth. Add -i for uppercase.

2 min read

Get new posts by email

One email when a new post is published. No spam.

Unsubscribe in one click. No spam, ever.