如何测试有效的UUID / GUID?


270

如何检查变量是否包含有效的UUID / GUID标识符?

我目前仅对验证类型1和4感兴趣,但这不应该限制您的答案。


以字符串格式,而不是十六进制,不是bin,或者我不知道您要什么
Marek Sebera 2011年

^(\ {){0,1} [0-9a-fA-F] {4} \-[0-9a-fA-F] {4} \-[0-9a-fA-F] {4} \-[0-9a-fA-F] {4} \-[0-9a-fA-F] {12}(\}){0,1} $
Brandon Moretz

如果您不能排除包含32个连续十六进制数字链(不分组)的变量,请看一下我的答案
Wolf

Answers:


413

当前,UUID如RFC4122中所指定。一个经常被忽略的边缘情况是NIL UUID,在此指出。以下正则表达式将这一点考虑在内,并将返回NIL UUID的匹配项。请参阅以下有关仅接受非NIL UUID的UUID。这两种解决方案均适用于版本1至5(请参见第三个模块的第一个字符)。

因此,要验证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

...确保您拥有规范版本1至5的UUID,并且是RFC4122的适当变体。

注意:大括号{}不是规范的。它们是某些系统和用法的产物。

轻松修改上面的正则表达式以满足原始问题的要求。

提示:正则表达式组/捕获

为了避免匹配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


1
我认为[1-5] [0-9a-f] {3}是错误的。我有一个有效的UUID,在该部分中带有“ b06a”,这对我来说是失败的。
Felipe Brahm 2014年

1
@FelipeBrahm,根据RFC,[1-5]是正确的,4位表示版本,只有5个版本。
rvignacio 2014年

749d0000-0194-1005-2e05-08d61613bf2f在小提琴中对我失败
抢劫

1
出于好奇,(为什么)以下内容也无效: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}
tjeerdnet

58

正则表达式进行救援

/^[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');

或带括号

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

3
或是否有括号:/ ^ \ {?[0-9a-fA-F] {4}-[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');
ryanb

这不是很正确。它错过了[1-5](版本)开始第三个程序段,而[89AB](变量)开始了第四个程序段。Gambol的答案正确。

7
更简洁的版本(忽略括号):/^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/i
c24w

41

如果要检查或验证特定的UUID版本,请参见以下相应的正则表达式。

请注意,唯一的区别是版本号,这在UUID 4122 RFC的4.1.3. Version章节中进行了说明。

版本号是第三组的第一个字符[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

39

如果使用Node.js进行开发,建议使用一个名为Validator的软件包。它包含验证不同版本的UUID所需的所有正则表达式,此外还提供其他各种验证功能。

这是npm链接:验证程序

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

有趣,但是看起来要连字符了吗?这是它当前使用的四个正则表达式/^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i 和/或 /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i 和/或 /^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i 和/或 /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i
ruffin

1
验证程序仅支持UUID v3-5,不支持v1
peteb,2016年

13

除了在几乎所有情况下都能胜任的Gambol答案外,到目前为止给出的所有答案都没有想到,分组格式(8-4-4-4-12)并不是将GUID编码为文本所必需的。它使用得非常频繁,但显然32位十六进制数字的纯链可能也是有效的。[1] 正则表达式enh

/^[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]所述的问题是关于校验荷兰国际集团变量 S,所以我们应该包括用户不友好的形式为好。


这是我的最爱。甚至更好{?[0-9a-f]{8}-?[0-9a-f]{4}-?[1-5][0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}}?
迈克·内尔森

10

到目前为止发布的所有特定于类型的正则表达式都在RFC 4.1.7中定义为“ type 0”的Nil UUID上失败:

nil UUID是UUID的一种特殊形式,它指定将所有128位都设置为零: 00000000-0000-0000-0000-000000000000

修改Wolf的答案:

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

或者,要正确排除不带全零的“类型0”,我们有以下内容(感谢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

在零UUID的第一UUID段应该有8个零,而不是7所提供的正则表达式不随7.验证它
富Seviora

2
您的看起来更好,但允许一些无效的UUID,例如:abcdef00-0000-0000-0000-000000000000 将与您的正则表达式匹配。此正则表达式将匹配有效的UUID,包括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
Luke

10

感谢@usertatha进行一些修改

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;
}

2

我认为Gambol的答案几乎是完美的,但却曲解了RFC 4122§4.1.1。变体部分

它涵盖Variant-1 UUID(10xx = 8..b),但不涵盖为向后兼容保留的Variant-0(0xxx = 0..7)和Variant-2(110x = c..d)变体,因此它们在技术上是有效的UUID。实际上,变体4(111x = e..f)保留供将来使用,因此它们当前无效。

同样,0类型无效,只有当它是NIL UUID时才允许将“数字”设为0(就像在Evan的答案中提到的那样)。

因此,我认为符合当前RFC 4122规范的最准确的正则表达式是(包括连字符):

/^([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)

1

使用.match()方法检查String是否为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}$");
}

未捕获的TypeError:s.matches不是函数
Deep Kakkar

1
给定的脚本不是Javascript,这是OP要求的。
StefanJanssen

调整了答案以解决以上评论。解决方案现在按预期工作。
DeeZone

仍然不是js。
ktilcu

1

以上答案的略微修改版本以更简洁的方式编写。这将验证任何带连字符的GUID(但是可以轻松修改以使连字符为可选)。这也将支持大写和小写字符,无论规范如何,该字符已成为惯例:

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

这里的关键是下面的重复部分

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

只需将4个字符模式重复3次


1
A-f应该是A-F这样的:/^([0-9a-fA-F]{8})-(([0-9a-fA-F]{4}\-){3})([0-9a-fA-F]{12})$/i
DeeZone

如果您输入大小写(/ i),为什么要重复AF,然后再重复AF?
Nimrod

0

在Node中执行此操作的一个好方法是使用ajv包(https://github.com/epoberezkin/ajv)。

const Ajv = require('ajv');
const ajv = new Ajv({ allErrors: true, useDefault: 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

-1

我认为更好的方法是使用静态方法fromString来避免那些正则表达式。

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

另一方面

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

抛出java.lang.IllegalArgumentException:无效的UUID字符串:x

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.