Match any UUID
Match the 8-4-4-4-12 hex shape shared by every UUID version, for code paths that just need to recognize an identifier, not enforce its version.
Last updated
\b[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\bMatches
- id 123e4567-e89b-12d3-a456-426614174000 was issued
- ID f47AC10B-58CC-4372-A567-0E02B2C3D479 works too
Doesn’t match
- not-a-uuid-at-all-nope
- 123e4567-e89b-12d3-a456-42661417400
Why it’s written this way
The five hex groups of length 8-4-4-4-12, joined by literal hyphens, are the one thing every UUID version has in common — this pattern deliberately stops there instead of pinning down the version nibble or the variant bits.
That is the key difference from a v4-only pattern, which additionally locks the first character of the third group to '4' and constrains the first character of the fourth group to 8, 9, a or b. Use this looser pattern when you need to recognize 'something UUID-shaped' from any generator; use the v4 pattern when you specifically need to enforce that a client sent a v4 id.
Edge cases to know
- →It accepts version and variant bits that don't correspond to any assigned UUID version — the all-zero nil UUID and made-up strings like ffffffff-ffff-ffff-ffff-ffffffffffff both match.
- →It has no opinion on braces or the urn:uuid: prefix some systems wrap UUIDs in — strip those separately if present.
- →Case-insensitivity means it treats uppercase and lowercase hex as equivalent, even though most systems normalize to one case internally.
Part by part
- [0-9a-fA-F]{8}
- The first group of the 8-4-4-4-12 layout. Both cases listed, so the pattern behaves the same with or without the i flag.
- [0-9a-fA-F]{12}
- The final and longest group.
- \b
- Word boundaries, which stop the match starting or ending inside a longer hexadecimal string such as a hash.
Common mistakes
[0-9a-fA-F-]{36}Counting characters rather than describing structure accepts thirty-six hyphens and rejects nothing meaningful. The 8-4-4-4-12 shape is the entire specification of the format.
\b[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}Lowercase only, with no i flag, misses the uppercase form that .NET and several databases produce by default — so it works on your data and fails on theirs.
[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}This is the v4 pattern, not the any-version one. It is correct for its own purpose and wrong here — it silently drops v1 and v7 identifiers, which is the opposite of what a general matcher should do.
Questions
Why match any version rather than just v4?
Because you are usually finding identifiers in logs or input rather than auditing how they were generated. Restricting to v4 there means quietly skipping v1 and v7 values that are perfectly valid identifiers in your system.
What do the other versions actually mean?
Version 1 encodes a timestamp and a MAC address, version 4 is random, and version 7 is a newer time-ordered format designed to index well in databases. Version 1 is the one with privacy implications, since it can leak the generating machine.
Does it match the braced or URN forms?
No. Windows often writes {550e8400-...} with braces, and the URN form prefixes urn:uuid:. Both need their own handling — strip the wrapper before matching, or add optional groups around this pattern.
Why the word boundaries?
Without them the pattern can start partway through a longer hex string, such as a SHA hash with hyphens inserted, and report a UUID that is really a fragment of something else.