45

如何验证值是否等于此代码生成的 UUID4?

uuid.uuid4().hex

它应该是一些正则表达式吗?这种形式的 32 个字符长的字符串生成的值:

60e3bcbff6c1464b8aed5be0fce86052
4

4 回答 4

123

据我所知,Martijn 的回答并非 100% 正确。一个 UUID-4 有五组十六进制字符,第一组 8 个字符,第二组 4 个字符,第三组 4 个字符,第四组 4 个字符,第五组 12 个字符。

但是,要使其成为有效的 UUID4,第三组(中间的那一组)必须以 4 开头:

00000000-0000-4000-0000-000000000000
              ^

第四组必须以 8、9、a 或 b 开头。

00000000-0000-4000-a000-000000000000
              ^    ^

因此,您必须将Martijn 的正则表达式更改为:

import re
uuid4hex = re.compile('[0-9a-f]{12}4[0-9a-f]{3}[89ab][0-9a-f]{15}\Z', re.I)

希望这可以帮助!

于 2013-08-21T13:40:17.757 回答
55

更具体。这是捕获带有和不带有破折号的 uuid4 的最精确的正则表达式,并且遵循 UUID4 的所有规则:

[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}

您可以确保它也可以通过忽略大小写来捕获大写字母。在我与 re.I. 的示例中。(uuid 的输出中没有大写字母,但在输入中它不会失败,只是忽略它。这意味着在 UUID 中“f”和“F”是相同的)

我创建了一个验证器来捕捉它们,如下所示:

def valid_uuid(uuid):
    regex = re.compile('^[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}\Z', re.I)
    match = regex.match(uuid)
    return bool(match)

然后你可以这样做:

if valid_uuid(my_uuid):
    #Do stuff with valid my_uuid

以 ^ 开头, \Z 结尾,我还确保字符串中没有其他内容。这确保“3fc3d0e9-1efb-4eef-ace6-d9d59b62fec5”返回 true,但“3fc3d0e9-1efb-4eef-ace6-d9d59b62fec5+19187”返回 false。

更新 - 下面的 python 方式并非万无一失 - 请参阅评论

还有其他方法可以验证 UUID。在蟒蛇做:

from uuid import UUID
try:
    UUID(my_uuid)
    #my_uuid is valid and you can use it
except ValueError:
    #do what you need when my_uuid is not a uuid
于 2013-08-29T16:18:54.227 回答
24

很简单:

import re
uuid4hex = re.compile('[0-9a-f]{32}\Z', re.I)

这仅匹配正好是32 个十六进制字符的字符串,前提是您使用该.match()方法(从字符串的开头搜索,请参阅.search()vs..match())。匹配字符串的\Z结尾(与$匹配字符串换行符的结尾)。

于 2012-07-08T16:10:30.800 回答
2

作为对性能问题的帮助说明,我已经在执行时间方面测试了两种方式,并且正则表达式验证方法要快得多:

import re
from uuid import UUID


def _validate_uuid4(uuid_string):
    try:
        UUID(uuid_string, version=4)
    except ValueError:
        return False
    return True

def _validate_uuid4_re(uuid_string):
    uuid4hex = re.compile('^[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}\Z', re.I)
    match = uuid4hex.match(uuid_string)
    return bool(match)

ipython命令中:

在 [58] 中:val = str(uuid.uuid4())

输入 [59]:%time _validate_uuid4(val) CPU 时间:用户 0 ns,系统:0 ns,总计:0 ns 挂壁时间:30.3 µs 输出[59]:真

输入 [60]:%time _validate_uuid4_re(val) CPU 时间:用户 0 ns,系统:0 ns,总计:0 ns 挂壁时间:25.3 µs 输出[60]:真

在 [61] 中:val = "invalid_uuid"

输入 [62]:%time _validate_uuid4(val) CPU 时间:用户 0 ns,系统:0 ns,总计:0 ns 挂壁时间:29.3 µs 输出[62]:假

输入 [63]:%time _validate_uuid4_re(val) CPU 时间:用户 0 ns,系统:0 ns,总计:0 ns 壁时间:25.5 µs 输出[63]:假

于 2019-06-07T10:32:01.670 回答