Developer Toolbox

Regex: UUID

A UUID is 32 hex digits in groups of 8, 4, 4, 4 and 12. This pattern also checks the two digits that carry meaning: the version (1 to 8) and the variant (8, 9, a or b), so a random 36-character string with dashes in the right places does not pass.

Open in Regex Tester The pattern and every example below are filled in.

Pattern

^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$

Flags: i

How it works

^
Start of the string.
[0-9a-f]{8}-
Eight hex digits and a dash.
[0-9a-f]{4}-
Four hex digits and a dash.
[1-8][0-9a-f]{3}-
The version digit (1 to 8), three more hex digits, a dash.
[89ab][0-9a-f]{3}-
The variant digit (8, 9, a or b for RFC 9562 UUIDs), three more, a dash.
[0-9a-f]{12}
Twelve hex digits.
$
End of the string. The i flag accepts upper case too.

Matches

  • 123e4567-e89b-12d3-a456-426614174000
  • 550E8400-E29B-41D4-A716-446655440000
  • 018f3c2e-7b1a-7c3d-9e4f-0123456789ab

Doesn't match

  • 123e4567e89b12d3a456426614174000
  • 00000000-0000-0000-0000-000000000000
  • 123e4567-e89b-12d3-c456-426614174000
  • {123e4567-e89b-12d3-a456-426614174000}

In your language

JavaScript
/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i

A literal; new RegExp(source, flags) builds the same from a string.

Python
re.compile(r"^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", re.IGNORECASE)

A raw string, so backslashes reach re as written. re.ASCII keeps \d to 0-9, as in JavaScript (Python matches any Unicode digit otherwise). Use re.fullmatch to test a whole string.

Java
Pattern.compile("^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", Pattern.CASE_INSENSITIVE)

A normal string literal, so every backslash is doubled. matcher(s).matches() tests the whole string.

Go
regexp.MustCompile(`(?i)^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$`)

A raw string in backticks. RE2 runs in linear time but has no lookaround and no backreferences.

PHP
preg_match('/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iD', $input)

PCRE with / delimiters inside a single-quoted string. Without the D modifier, $ also matches before a final newline, so it is added to patterns that end in $.

C#
new Regex(@"^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", RegexOptions.IgnoreCase)

A verbatim string: backslashes stay, a quote is doubled. RegexOptions.ECMAScript keeps \d to 0-9, as in JavaScript. $ also matches before a final newline; to reject one, end the pattern with \z instead.

Common mistakes

  • The nil and max UUIDs fail

    00000000-0000-0000-0000-000000000000 and ffffffff-ffff-ffff-ffff-ffffffffffff are valid UUIDs with no version. Accept them by name if your data uses them.

  • Braces and URNs

    Windows tools print GUIDs in braces and some APIs send urn:uuid:.... Strip those before matching rather than widening the pattern.

  • Validating is not comparing

    The same UUID can arrive in upper or lower case. Lower-case UUIDs before comparing or storing them.