我正在使用正则表达式在文本块中搜索uuid。目前,我依赖于所有uuid都遵循8-4-4-4-12十六进制数字模式的假设。

有人能想到这样一个用例吗?在这个用例中,这个假设是无效的,并且会导致我错过一些uuid。


当前回答

如果使用POSIX正则表达式(grep -E, MySQL等),这可能更容易阅读和记忆:

[[:xdigit:]]{8}(-[[:xdigit:]]{4}){3}-[[:xdigit:]]{12}

Perl和PCRE版本也支持POSIX字符类,因此可以与它们一起工作。对于这些,将(…)更改为非捕获子组(?:…)。

JavaScript(以及其他支持Unicode属性的语法)可以使用类似的易读版本:

/\p{Hex_Digit}{8}(?:-\p{Hex_Digit}{4}){3}-\p{Hex_Digit}{12}/u

其他回答

想要给出我的贡献,因为我的regex涵盖了OP的所有情况,并正确地将组方法上的所有相关数据分组(你不需要post处理字符串来获得uuid的每个部分,这个regex已经为你获得了它)

([\d\w]{8})-?([\d\w]{4})-?([\d\w]{4})-?([\d\w]{4})-?([\d\w]{12})|[{0x]*([\d\w]{8})[0x, ]{4}([\d\w]{4})[0x, ]{4}([\d\w]{4})[0x, {]{5}([\d\w]{2})[0x, ]{4}([\d\w]{2})[0x, ]{4}([\d\w]{2})[0x, ]{4}([\d\w]{2})[0x, ]{4}([\d\w]{2})[0x, ]{4}([\d\w]{2})[0x, ]{4}([\d\w]{2})[0x, ]{4}([\d\w]{2})

UUID可以有大写字母。所以你需要toLowerCase()字符串或使用:

[a-fA-F0-9] {8} - {4} [a-fA-F0-9] [a-fA-F0-9] {4} - {4} [a-fA-F0-9] [a-fA-F0-9] {12}

本想评论一下,但没有足够的代表:)

uuid的正则表达式是:

[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}

如果你想强制整个字符串来匹配这个正则表达式,你有时(你的匹配器API可能有一个方法)需要用^…$,即

^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$

版本4的uuid形式为xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx,其中x是任何十六进制数字,y是8,9,A或b中的一个,例如f47ac10b-58cc-4372-a567-0e02b2c3d479。

来源:http://en.wikipedia.org/wiki/Uuid定义

因此,从技术上讲,这是更正确的:

/[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}/

在python re中,你可以从数字到大写alpha。所以. .

import re
test = "01234ABCDEFGHIJKabcdefghijk01234abcdefghijkABCDEFGHIJK"
re.compile(r'[0-f]+').findall(test) # Bad: matches all uppercase alpha chars
## ['01234ABCDEFGHIJKabcdef', '01234abcdef', 'ABCDEFGHIJK']
re.compile(r'[0-F]+').findall(test) # Partial: does not match lowercase hex chars
## ['01234ABCDEF', '01234', 'ABCDEF']
re.compile(r'[0-F]+', re.I).findall(test) # Good
## ['01234ABCDEF', 'abcdef', '01234abcdef', 'ABCDEF']
re.compile(r'[0-f]+', re.I).findall(test) # Good
## ['01234ABCDEF', 'abcdef', '01234abcdef', 'ABCDEF']
re.compile(r'[0-Fa-f]+').findall(test) # Good (with uppercase-only magic)
## ['01234ABCDEF', 'abcdef', '01234abcdef', 'ABCDEF']
re.compile(r'[0-9a-fA-F]+').findall(test) # Good (with no magic)
## ['01234ABCDEF', 'abcdef', '01234abcdef', 'ABCDEF']

这使得最简单的Python UUID正则表达式:

re_uuid = re.compile("[0-F]{8}-([0-F]{4}-){3}[0-F]{12}", re.I)

我将把使用timeit来比较它们的性能作为读者的练习。

享受。 保持python™!

注意:这些跨度也将匹配:;<=>?所以,如果你怀疑这可能会给你假阳性,不要走捷径。(感谢Oliver Aubert在评论中指出这一点。)