ChatGPT解决这个技术问题 Extra ChatGPT

如何测试有效的 UUID/GUID?

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

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

字符串格式,不是十六进制,不是bin,或者我不知道你要什么
如果您不能排除包含 32 个连续十六进制数字链的变量(不分组),请查看 my answer

C
Community

目前,UUID 在 RFC4122 中指定。一个经常被忽视的边缘情况是 NIL UUID,请注意 here。以下正则表达式考虑了这一点,并将返回 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

...确保您有一个规范格式的 UUID,它是版本 1 到 5,并且是符合 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-5][0-9a-f]{3} 不正确。我有一个有效的 UUID,在那部分有“b06a”,这对我来说失败了。
@FelipeBrahm,根据RFC,[1-5]是正确的,4位表示版本,只有5个版本。
749d0000-0194-1005-2e05-08d61613bf2f 在小提琴中对我来说失败了
出于好奇,(为什么)以下内容也无效:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}
@mshaffer 第 21 行,第二个正则表达式定义似乎不正确,第一个没问题 - 验证空正则表达式和抢劫正则表达式,第二个 def 未能做到。
I
Ivan Gabriele

如果您想检查或验证特定的 UUID 版本,这里是相应的正则表达式。

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

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


有趣的是,我有一个由 C# 创建的 Guid,它与其中任何一个都不匹配,因为它有一个“c”,正则表达式需要 8,9,A 或 B。
M
Marek Sebera

正则表达式来救援

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

或者如果您可能有括号:/^\{?[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');
这不太正确。它错过了 [1-5](版本)开始第 3 个块,而 [89AB](变体)开始第 4 个块。 Gambol's answer 做得对。
更简洁的版本(忽略括号):/^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/i
M
Marek Sebera

如果您使用 Node.js 进行开发,建议使用名为 Validator 的包。它包括验证不同版本的 UUID 所需的所有正则表达式,并且您可以获得各种其他验证功能。

这是 npm 链接:Validator

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

有趣,但它看起来需要连字符? 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 和/或 /^[0-9A-F]{8}-[0-9A-F]/^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i-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]/^[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]/^[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]/^[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]{12}$/i
Validator 仅支持 UUID v3-5 不支持 v1
S
Souhaieb

感谢@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;
}


您可以使用 .test() 而不是 .match() 并返回它。
C
Community

除了 Gambol's answer 将在几乎所有情况下完成工作之外,到目前为止给出的所有答案都忽略了分组格式 (8-4-4-4-12) 对 encode GUIDs in text 不是强制性的。它的使用非常频繁,但显然 32 位十六进制数字的普通链也是有效的。[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] 问题是关于检查变量的,所以我们也应该包括对用户不友好的表单。

为什么 .NET GUID 中有破折号? - 堆栈溢出加上接受的答案

测试和验证 GUID (guid.us)

Guid.ToString 方法(字符串)(MSDN)


这是我的最爱。更好{?[0-9a-f]{8}-?[0-9a-f]{4}-?[1-5][0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}}?
如果您使用 RFC4122 作为指南,则必须使用连字符。其他一些来源(例如 Microsoft)可能会在某些地方使用无连字符的 GUID。如果此答案想讨论检查 VARIABLES 是否有有效的 128 位值,则有无数种方法可以在变量中编码 128 位值。此答案仅解决一个变量编码,即字符串中的 32 个十六进制字符,这不是 RFC4122 编码。我很遗憾我不得不研究连字符是否是可选的。根据 RFC4122,它们不是。
c
configbug

如果你使用 uuid 包,这个包会带来一个布尔验证函数,它会告诉你一个 uuid 是否有效。

例子:

import { validate as isValidUUID } from 'uuid';

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

极好的!对于我们这些已经在 JS 中生成 UUID 的人来说,这比公认的解决方案要好。
是不是 2012 年的解决方案
效果很好!!!!
E
Evan Edwards

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

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

nil UUID 的第一个 UUID 段应该有 8 个零,而不是 7。提供的正则表达式没有用 7 验证它。
你的看起来更好,但允许一些无效的 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
w
wellington

如果您使用 uuid 包,您可以导入 validate 并将 id 传递给它

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

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

C
Community

我认为 Gambol's answer 几乎是完美的,但它有点误解了 RFC 4122 § 4.1.1. Variant section

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

此外,0 类型是无效的,“数字”只有在它是 NIL UUID 时才允许为 0(如 Evan's answer 中提到的)。

所以我认为符合当前 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)

N
NS23

如果有人使用 yup ,JavaScript 模式验证器库,可以使用以下代码实现此功能。

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

我在尝试此操作时收到此错误消息:Property 'uuid' does not exist on type 'StringSchema<string>'. 它仍然对您有用吗?
@ThomasSoos 你能分享你的代码片段吗?
我试过你的代码片段......
在 runkit npm.runkit.com/yup 上尝试了此代码,它仍然对我有用
J
James Morrison

以更简洁的方式编写的上述答案的略微修改版本。这将验证任何带有连字符的 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 次


A-f 应该是 A-F 像这样:/^([0-9a-fA-F]{8})-(([0-9a-fA-F]{4}\-){3})([0-9a-fA-F]{12})$/i
如果您忽略大小写 (/i),为什么要重复 af 然后 AF?
b
blackcatweb

在 Node 中执行此操作的一个好方法是使用 ajv 包 (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

谢谢,你能更新你的答案的一行吗,const ajv = new Ajv({ allErrors: true, useDefaults: true, verbose: true }); useDefaults not useDefault
完成 - 您现在可以删除您的评论。
D
DeeZone

使用 .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 不是函数
给定的脚本不是 Javascript,这是 OP 要求的。
调整答案以解决上述评论。解决方案现在按预期工作。
那仍然不是js。
@ktilcu 这是在 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

版本 1 到 5,省略版本时不使用多版本正则表达式。

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)); } } 返回假; } // 测试 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' , 'AAAAAAA-1111-1111-AAAG-111111111111', ]; valid.forEach(test => console.log("有效案例,结果:"+isUUID(test))); invalid.forEach(test => console.log("无效的情况,结果:"+isUUID(test)));


D
Daniel Heid

我向 Apache Commons Validator 添加了一个 UUID 验证器。它尚未合并,但您可以在这里投票:

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


仅仅因为“Javascript”的名称中包含“Java”,并不意味着它是一个 Java 问题。
s
s3c

我有这个功能,但它与接受的答案基本相同。

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

我认为更好的方法是使用静态方法 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


问题是针对 Javascript 的。这个答案也可以在 JS 中使用吗?该异常看起来像 Java 异常。