ChatGPT解决这个技术问题 Extra ChatGPT

How to test valid UUID/GUID?

How to check if variable contains valid UUID/GUID identifier?

I'm currently interested only in validating types 1 and 4, but it should not be a limitation to your answers.

in string format, not hex, not bin, or I don't know what do you ask for
If you cannot exclude variables containing a chain of 32 consecutive hex digits (without grouping), have a look at my answer

C
Community

Currently, UUID's are as specified in RFC4122. An often neglected edge case is the NIL UUID, noted here. The following regex takes this into account and will return a match for a NIL UUID. See below for a UUID which only accepts non-NIL UUIDs. Both of these solutions are for versions 1 to 5 (see the first character of the third block).

Therefore to validate a UUID...

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

...ensures you have a canonically formatted UUID that is Version 1 through 5 and is the appropriate Variant as per RFC4122.

NOTE: Braces { and } are not canonical. They are an artifact of some systems and usages.

Easy to modify the above regex to meet the requirements of the original question.

HINT: regex group/captures

To avoid matching NIL UUID:

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

I think [1-5][0-9a-f]{3} is incorrect. I have a valid UUID which has "b06a" in that part, and this was failing for me.
@FelipeBrahm, [1-5] is right according to RFC, that 4 bits indicate the version, and there are only 5 versions.
749d0000-0194-1005-2e05-08d61613bf2f fails for me in the fiddle
Out of curiosity, (why) wouldn't the following be valid too: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}
@mshaffer the line 21, second regex definition seems incorrect, the first one is ok - validates both empty and robs regex, which second def fails to do.
I
Ivan Gabriele

If you want to check or validate a specific UUID version, here are the corresponding regexes.

Note that the only difference is the version number, which is explained in 4.1.3. Version chapter of UUID 4122 RFC.

The version number is the first character of the third group : [VERSION_NUMBER][0-9A-F]{3} :

UUID v1 : /^[0-9A-F]{8}-[0-9A-F]{4}-[1][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i

UUID v2 : /^[0-9A-F]{8}-[0-9A-F]{4}-[2][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i

UUID v3 : /^[0-9A-F]{8}-[0-9A-F]{4}-[3][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i

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

UUID v5 : /^[0-9A-F]{8}-[0-9A-F]{4}-[5][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i


Interesting, I have a Guid created by C# that doesn't match any of these because it has a 'c' where the regex is expecting 8,9,A, or B.
M
Marek Sebera

regex to the rescue

/^[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}$/.test('01234567-9ABC-DEF0-1234-56789ABCDEF0');

or with brackets

/^\{?[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}‌​\}?$/

or if you might have brackets: /^\{?[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}\}?$/.test('01234567-9ABC-DEF0-1234-56789ABCDEF0');
This isn't quite correct. it misses that [1-5] (version) starts the 3rd block and [89AB] (variant) starts the 4th block. Gambol's answer does it right.
More concise version (ignoring brackets): /^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/i
M
Marek Sebera

If you are using Node.js for development, it is recommended to use a package called Validator. It includes all the regexes required to validate different versions of UUID's plus you get various other functions for validation.

Here is the npm link: Validator

var a = 'd3aa88e2-c754-41e0-8ba6-4198a34aa0a2'
v.isUUID(a)
true
v.isUUID('abc')
false
v.isNull(a)
false

Interesting, but it looks like it expects hyphens? Here are the four regexes it's currently using -- /^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i and/or /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i and/or /^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i and/or /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i
Validator only supports UUID v3-5 not v1
S
Souhaieb

thanks to @usertatha with some modification

function isUUID ( uuid ) {
    let s = "" + uuid;

    s = s.match('^[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}$');
    if (s === null) {
      return false;
    }
    return true;
}


You could utilize .test() instead of .match() and just return that.
C
Community

Beside Gambol's answer that will do the job in nearly all cases, all answers given so far missed that the grouped formatting (8-4-4-4-12) is not mandatory to encode GUIDs in text. It's used extremely often but obviously also a plain chain of 32 hexadecimal digits can be valid.[1] regexenh:

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

[1] The question is about checking variables, so we should include the user-unfriendly form as well.

Why are there dashes in a .NET GUID? - Stack Overflow plus Accepted answer

Test and validate a GUID (guid.us)

Guid.ToString Method (String) (MSDN)


This one is my fave. Even better {?[0-9a-f]{8}-?[0-9a-f]{4}-?[1-5][0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}}?
If you use RFC4122 as your guide, you must have the hyphens. Some other sources, such as Microsoft may use hyphen-less GUIDs in some places. If this answer wants to discuss checking VARIABLES for a valid 128bit value, there are infinite ways to to encode a 128 bit value in variables. This answer only addresses one variable encoding, of 32 hex chars in a string, which is not an RFC4122 encoding. I'm sad I had to research if the hyphens are optional. Per RFC4122, they are not.
c
configbug

If you use the uuid package, this package brings a boolean validation function where it tells you if a uuid is valid or not.

Example:

import { validate as isValidUUID } from 'uuid';

if (!isValidUUID(tx.originId)) {
  return Promise.reject('Invalid OriginID');
}

Fantastic! Better than the accepted solution for those of us already generating the UUIDs in JS.
is that it was a 2012 solution
Works great!!!!
E
Evan Edwards

All type-specific regexes posted so far are failing on the "type 0" Nil UUID, defined in 4.1.7 of the RFC as:

The nil UUID is special form of UUID that is specified to have all 128 bits set to zero: 00000000-0000-0000-0000-000000000000

To modify Wolf's answer:

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

Or, to properly exclude a "type 0" without all zeros, we have the following (thanks to Luke):

/^(?:[0-9a-f]{8}-?[0-9a-f]{4}-?[1-5][0-9a-f]{3}-?[89ab][0-9a‌​-f]{3}-?[0-9a-f]{12}‌​|00000000-0000-0000-‌​0000-000000000000)$/‌​i

First UUID segment of the nil UUID should have 8 zeroes, not 7. The regex provided did not validate it with 7.
Yours looks nicer but allows some invalid UUIDs eg: abcdef00-0000-0000-0000-000000000000 would match your regex. This regex will match valid UUIDs, including the nil: /^(?:[0-9a-f]{8}-?[0-9a-f]{4}-?[1-5][0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i
w
wellington

if you use the uuid package, you can import the validate and pass the id into it

const { v4: uuidv4, validate } = require('uuid');

const { id } = request.params;
validate(id) ? true : false;

C
Community

I think Gambol's answer is almost perfect, but it misinterprets the RFC 4122 § 4.1.1. Variant section a bit.

It covers Variant-1 UUIDs (10xx = 8..b), but does not cover Variant-0 (0xxx = 0..7) and Variant-2 (110x = c..d) variants which are reserved for backward compatibility, so they are technically valid UUIDs. Variant-4 (111x = e..f) is indeed reserved for future use, so they are not valid currently.

Also, 0 type is not valid, that "digit" is only allowed to be 0 if it's a NIL UUID (like mentioned in Evan's answer).

So I think the most accurate regex that complies with current RFC 4122 specification is (including hyphens):

/^([0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[0-9a-d][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i
                            ^                ^^^^^^
                    (0 type is not valid)  (only e..f variant digit is invalid currently)

N
NS23

If someone is using yup , JavaScript schema validator library, This functionality can be achieved with below code.

const schema = yup.object().shape({
   uuid: yup.string().uuid()
 });
 const isValid = schema.isValidSync({uuid:"string"});

I get this error message trying this: Property 'uuid' does not exist on type 'StringSchema<string>'. Does it still work for you?
@ThomasSoos Can you share your code snippet ?
I tried your code snippet...
Tried this code on runkit npm.runkit.com/yup , its still working for me
J
James Morrison

A slightly modified version of the above answers written in a more concise way. This will validate any GUID with hyphens (however easily modified to make hyphens optional). This will also support upper and lower case characters which has become the convention regardless of the specification:

/^([0-9a-fA-F]{8})-(([0-9a-fA-F]{4}\-){3})([0-9a-fA-F]{12})$/i

The key here is the repeating part below

(([0-9a-fA-F]{4}\-){3})

Which simply repeats the 4 char patterns 3 times


A-f should be A-F like so: /^([0-9a-fA-F]{8})-(([0-9a-fA-F]{4}\-){3})([0-9a-fA-F]{12})$/i
if you ingore case (/i), why repeat a-f and then A-F?
b
blackcatweb

A good way to do it in Node is to use the ajv package (https://github.com/epoberezkin/ajv).

const Ajv = require('ajv');
const ajv = new Ajv({ allErrors: true, useDefaults: true, verbose: true });
const uuidSchema = { type: 'string', format: 'uuid' };
ajv.validate(uuidSchema, 'bogus'); // returns false
ajv.validate(uuidSchema, 'd42a8273-a4fe-4eb2-b4ee-c1fc57eb9865'); // returns true with v4 GUID
ajv.validate(uuidSchema, '892717ce-3bd8-11ea-b77f-2e728ce88125'); // returns true with a v1 GUID

thanks, can u update one line of your answer, const ajv = new Ajv({ allErrors: true, useDefaults: true, verbose: true }); useDefaults not useDefault
Done - you can delete your comment if you want now.
D
DeeZone

Use the .match() method to check whether String is UUID.

public boolean isUUID(String s){
    return s.match("^[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}$");
}

Uncaught TypeError: s.matches is not a function
The given script is not Javascript, which is what the OP asked for.
Adjusted answer to address comments above. Solution now works as expect.
That still isn't js.
@ktilcu This is in JS const isUUID = (uuid) => { return uuid.match( '^[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
Benjamin

Versions 1 to 5, without using a multi-version regex when version is omitted.

const uuid_patterns = { 1: /^[0-9A-F]{8}-[0-9A-F]{4}-1[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i, 2: /^[0-9A-F]{8}-[0-9A-F]{4}-2[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i, 3: /^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i, 4: /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i, 5: /^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i }; const isUUID = (input, version) => { if(typeof input === "string"){ if(Object.keys(uuid_patterns).includes(typeof version === "string" ? version : String(version))){ return uuid_patterns[version].test(input); } else { return Object.values(uuid_patterns).some(pattern => pattern.test(input)); } } return false; } // Testing let valid = [ 'A987FBC9-4BED-3078-CF07-9141BA07C9F3', 'A987FBC9-4BED-4078-8F07-9141BA07C9F3', 'A987FBC9-4BED-5078-AF07-9141BA07C9F3', ]; let invalid = [ '', 'xxxA987FBC9-4BED-3078-CF07-9141BA07C9F3', 'A987FBC9-4BED-3078-CF07-9141BA07C9F3xxx', 'A987FBC94BED3078CF079141BA07C9F3', '934859', '987FBC9-4BED-3078-CF07A-9141BA07C9F3', 'AAAAAAAA-1111-1111-AAAG-111111111111', ]; valid.forEach(test => console.log("Valid case, result: "+isUUID(test))); invalid.forEach(test => console.log("Invalid case, result: "+isUUID(test)));


D
Daniel Heid

I added a UUID validator to Apache Commons Validator. It's not yet been merged, but you can vote for it here:

https://github.com/apache/commons-validator/pull/68


Just because "Javascript" contains "Java" in the name, does not make it a Java question.
s
s3c

I have this function, but it's essentially the same as the accepted answer.

export default function isUuid(uuid: string, isNullable: boolean = false): boolean {
    return isNullable
        ? /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(uuid)
        : /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(uuid);
}

s
slfan

I think a better way is using the static method fromString to avoid those regular expressions.

    id = UUID.randomUUID();
    UUID uuid = UUID.fromString(id.toString());
    Assert.assertEquals(id.toString(), uuid.toString());

On the other hand

   UUID uuidFalse = UUID.fromString("x");

throws java.lang.IllegalArgumentException: Invalid UUID string: x


The question is for Javascript. Is this answer also usable in JS? The exception looks like a Java Exception.