The accepted answer has several flaws:
- It includes hidden characters that break the regex
- It does not allow for uppercase letters (some or all)
- It does not allow for optional dashes
See Wikipedia for details on allowed representations of a v4 UUID.
A regex check that meets the requirements above is:
preg_match(/(?i)[a-f0-9]{8}[\-]?[a-f0-9]{4}[\-]?4[a-f0-9]{3}[\-]?(8|9|a|b)[a-f0-9]{3}[\-]?[a-f0-9]{12}/, $uuid, $matches);
This option will meet most cases, however a more thorough version would address the following flaws:
- It doesn't allow for the
nil
UUID (all 0
) or the max
UUID (all F
)
- It doesn't allow for the Windows-based format that includes leading and trailing braces (
{...}
)
A regex check that meets these requirements as well is:
preg_match(/(?i){?[a-f0-9]{8}[\-]?[a-f0-9]{4}[\-]?(4[a-f0-9]{3}|[0]{4}|[F]{4})[\-]?((8|9|a|b)[a-f0-9]{3}|[0]{4}|[F]{4})[\-]?[a-f0-9]{12}}?/, $uuid, $matches);
These pieces mean:
(?i)
: force case insensitivity
{?
: 0 or 1 opening braces
[a-f0-9]{8}
: 8 allowed characters
[\-]?
: 0 or 1 dashes
[a-f0-9]{4}
: 4 allowed characters
[\-]?
: 0 or 1 dashes
(4[a-f0-9]{3}|[0]{4}|[F]{4})
: a 4 followed by 3 allowed characters, or 4 zeroes, or 4 Fs
[\-]?
: 0 or 1 dashes
((8|9|a|b)[a-f0-9]{3}|[0]{4}|[F]{4})
: a 4 followed by 3 allowed characters, or 4 zeroes, or 4 Fs
[\-]?
: 0 or 1 dashes
[a-f0-9]{12}
: 12 allowed characters
}?
: 0 or 1 closing braces
For any of you regex wizards out there, this could further be improved if it's possible to do the following:
- Require that if one dash is present, all four dashes must be present
- Only allow all zeroes or all Fs in some blocks if the entire UUID is all zeroes or Fs
- Only allow an opening or closing brace if both are present