Blog
Wild & Free Tools

UUID Regex: Validate UUID Format in JavaScript and Python

Last updated: March 2026 6 min read
Quick Answer

Table of Contents

  1. The Standard UUID v4 Regex
  2. Loose UUID Regex (Any Version)
  3. Validate UUID in JavaScript
  4. Validate UUID in Python
  5. UUID Regex in Go, Java, and PHP
  6. Common Validation Mistakes
  7. Generate UUIDs to Test Against
  8. Frequently Asked Questions

UUID validation fails silently — pass a malformed string as a primary key or API parameter and you get a confusing 404 or a cryptic database error instead of a clear message. The fix is a regex check at the boundary. This guide gives you the exact pattern for UUID v4, a looser variant for any UUID version, and copy-paste examples for the languages developers search for most.

The Standard UUID v4 Regex Pattern

UUID v4 has a fixed structure: 8-4-4-4-12 hexadecimal characters separated by hyphens. The version digit is always 4. The variant digit is 8, 9, a, or b.

Strict UUID v4 pattern:

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

Breaking it down:

Valid: 550e8400-e29b-41d4-a716-446655440000
Invalid: 550e8400-e29b-31d4-a716-446655440000 (version digit is 3, not 4)

Loose UUID Regex (Any Version)

If you are validating UUIDs from external systems — API responses, legacy databases, or user input — you may receive v1, v3, v5, or v7 UUIDs. Use the loose pattern:

/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i

This only checks the hyphen structure and hex characters — it does not enforce version or variant bits. It will pass any valid UUID regardless of version.

Trade-off: the loose pattern also passes some technically invalid UUIDs (e.g., all-zeros 00000000-0000-0000-0000-000000000000), which is usually fine for input validation but not for strict standards compliance.

Validate UUID in JavaScript

JavaScript function using the strict v4 pattern:

function isUUIDv4(str) {
  const re = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
  return re.test(str);
}

console.log(isUUIDv4("550e8400-e29b-41d4-a716-446655440000")); // true
console.log(isUUIDv4("not-a-uuid"));  // false
console.log(isUUIDv4("550e8400e29b41d4a716446655440000")); // false — missing hyphens

For TypeScript, add a type guard:

function isUUIDv4(value: string): value is string {
  return /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);
}

Express.js middleware example:

app.get("/items/:id", (req, res) => {
  if (!isUUIDv4(req.params.id)) {
    return res.status(400).json({ error: "Invalid ID format" });
  }
  // proceed
});
Sell Custom Apparel — We Handle Printing & Free Shipping

Validate UUID in Python

Python has two approaches: the built-in uuid module and a raw regex.

Using the uuid module (recommended):

import uuid

def is_valid_uuid_v4(val):
    try:
        obj = uuid.UUID(val, version=4)
    except ValueError:
        return False
    return str(obj) == val.lower()

print(is_valid_uuid_v4("550e8400-e29b-41d4-a716-446655440000"))  # True
print(is_valid_uuid_v4("not-a-uuid"))  # False

The uuid.UUID constructor raises ValueError on bad format. Passing version=4 additionally checks the version and variant bits.

Using regex directly (no imports needed):

import re

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

def is_uuid_v4(val):
    return bool(UUID_V4_RE.match(val))

Compile the pattern once at module level — do not recompile inside a loop.

UUID Regex in Go, Java, and PHP

Go:

package main

import (
    "regexp"
    "fmt"
)

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

func isUUIDv4(s string) bool {
    return uuidV4Re.MatchString(s)
}

fmt.Println(isUUIDv4("550e8400-e29b-41d4-a716-446655440000")) // true

Go tip: use MustCompile at package level so the regex compiles once at startup, not on every call.

Java:

import java.util.regex.Pattern;

Pattern UUID_PATTERN = Pattern.compile(
    "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$"
);

boolean isValid = UUID_PATTERN.matcher(input).matches();

Java alternative: UUID.fromString(input) throws IllegalArgumentException on bad format, but it accepts any UUID version — not just v4.

PHP:

function isUUIDv4(string $val): bool {
    return (bool) preg_match(
        "/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i",
        $val
    );
}

Common Validation Mistakes

Forgetting anchors — without ^ and $, the pattern matches UUIDs embedded inside longer strings. "prefix-550e8400-e29b-41d4-a716-446655440000-suffix" would pass. Always anchor.

Case sensitivity — UUIDs from crypto.randomUUID() are lowercase; UUIDs from Java or .NET may be uppercase. Always use the i flag or include both cases explicitly.

Not handling stripped format — some systems store UUIDs without hyphens: 550e8400e29b41d4a716446655440000. Your validator will fail these unless you normalize first:

function normalizeUUID(s) {
  return s.replace(/^([0-9a-f]{8})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{12})$/i,
    "$1-$2-$3-$4-$5");
}

Validating too late — validate at the API boundary, not buried inside business logic. Fail fast with a clear 400 error.

Generate Valid UUIDs to Test Against

Test your regex against real UUID v4 output using the Cheetah UUID Generator — it produces one or ten RFC-compliant UUID v4 values instantly with one click. Copy a UUID, paste it into your validator, confirm the pattern passes. Then modify a character (change the 4 to a 3 in the version position) and confirm the strict pattern fails while the loose pattern passes. This two-step test confirms both patterns behave correctly.

Generate UUID v4 Values to Test Your Regex

Grab one or ten RFC-compliant UUID v4 strings from the Cheetah UUID Generator and paste them straight into your validator. One click, zero configuration.

Open Free UUID Generator

Frequently Asked Questions

What is the regex for UUID v4?

/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i — this enforces the 8-4-4-4-12 structure, version digit 4, and the variant nibble (8, 9, a, or b).

How do I validate a UUID in JavaScript without a library?

Use a one-liner: /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(yourString). No imports needed.

Should I use the strict or loose UUID regex?

Strict (with version and variant checks) when you control UUID generation and know they are always v4. Loose (structure only) when you accept UUIDs from external sources that may use other versions.

Does the uuid module in Python validate format?

Yes. uuid.UUID(val, version=4) raises ValueError if the format is invalid or if it is not a version 4 UUID. This is more readable than raw regex and is the recommended approach in Python.

Why does my UUID regex fail on uppercase UUIDs?

Omitting the case-insensitive flag. Add the i flag (JavaScript, PHP, Go) or re.IGNORECASE (Python). UUID characters are hex so A-F are valid alongside a-f.

Brandon Hill
Brandon Hill Productivity & Tools Writer

Brandon spent six years as a project manager becoming the team's go-to "tools guy" — always finding a free solution first.

More articles by Brandon →
Launch Your Own Clothing Brand — No Inventory, No Risk