当前位置:  开发笔记 > 编程语言 > 正文

使用正则表达式在文本中搜索UUID

如何解决《使用正则表达式在文本中搜索UUID》经验,为你挑选了12个好方法。

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

任何人都可以想到一个用例,这个假设是无效的,会让我错过一些UUID吗?



1> Ivelin..:

uuid的正则表达式是:

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


@ cyber-monk:[0-9a-f]在含义和速度上与[a-f0-9]和[0123456789abcdef]相同,因为正则表达式无论如何都变成了状态机,每个十六进制数字变成了在州表中输入.有关其工作原理的入口,请参阅http://en.wikipedia.org/wiki/Nondeterministic_finite_automaton
做那个'[a-f0-9]`!因为它是十六进制!你的正则表达式(原样)可能会返回误报.
在某些情况下,您甚至可能想要[a-fA-F0-9]或[A-F0-9].
这个解决方案不太正确.它匹配每个RFC4122具有无效版本和变体字符的ID.在这方面,@ Gajus的解决方案更为正确.此外,RFC允许输入大写字符,因此添加[AF]是合适的.
@broofa,我看到你真的设置了每个只匹配与RFC一致的UUID的人.但是,我认为您不得不多次指出这一点是一个可靠的指标,并非所有UUID都会使用RFC版本和变体指标.UUID定义http://en.wikipedia.org/wiki/Uuid#Definition声明了一个简单的8-4-4-4-12模式和2 ^ 128种可能性.RFC仅代表其中的一部分.那么你想要匹配什么?子集,还是全部?
你可以压缩这个正则表达式:`[0-9a-f] {8} - (?:[0-9a-f] {4} - ){3} [0-9a-f] {12}` .
为模式+1,但我想知道[0-9a-f]可能表现更好,因为更多的随机十六进制数字将是一个数字而不是字母字符?

2> Matthew F. R..:

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

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

本来只是评论了这个,但没有足够的代表:)


通常你可以通过将模式定义为不区分大小写的模式后面的i来处理这个问题,这使得一个更清晰的模式:/ [0-9a-f] {8} - [0-9a-f] {4} - [0 -9a-F] {4} - [0-9A-F] {4} - [0-9A-F] {12}/I

3> Gajus..:

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

来源:http://en.wikipedia.org/wiki/Uuid#Definition

因此,这在技术上更正确:

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


你拒绝版本1到3和5.为什么?
也需要接受[AF].根据RFC4122的第3部分:'十六进制值',"通过"f"输出为小写字符**,并且对输入**'不区分大小写.另外`(:?8 | 9 | A | B)`可能稍微更具可读性[`89aAbB]
@elliottcable根据您的环境,只需使用`i`(不区分大小写)标志.

4> Ivan Gabriel..:

如果要检查或验证特定的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


正则表达式末尾的`i`标志着它不区分大小写.

5> Panos..:

我同意根据定义你的正则表达式不会遗漏任何UUID.但是,请注意,如果您特别针对Microsoft的全局唯一标识符(GUID)进行搜索,则GUID有五个等效的字符串表示形式:

"ca761232ed4211cebacd00aa0057b223" 

"CA761232-ED42-11CE-BACD-00AA0057B223" 

"{CA761232-ED42-11CE-BACD-00AA0057B223}" 

"(CA761232-ED42-11CE-BACD-00AA0057B223)" 

"{0xCA761232, 0xED42, 0x11CE, {0xBA, 0xCD, 0x00, 0xAA, 0x00, 0x57, 0xB2, 0x23}}" 


在什么情况下会找到第一个模式?即是否有.Net函数将剥离连字符或返回没有连字符的GUID?

6> iGEL..:
/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89AB][0-9a-f]{3}-[0-9a-f]{12}$/i

Gajus的正则表达式拒绝UUID V1-3和5,即使它们是有效的.



7> JimP..:

[\w]{8}(-[\w]{4}){3}-[\w]{12} 在大多数情况下,我一直在为我工作

或者如果你想要真正具体[\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12}.


值得注意的是,至少在Java中,\ w匹配_以及十六进制数字.用\ p {XDigit}替换\ w可能更合适,因为它是为匹配十六进制数字而定义的POSIX类.当使用其他Unicode字符集时,这可能会中断.
@tom该字符串(2wt ...)是无效的UUID,但此答案中给出的模式与该字符串匹配,表明它是有效的UUID.太糟糕了,我不记得为什么UUID无效.

8> Bruno Bronos..:

在python中,你可以从数字到大写的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来比较它们的性能.

请享用.保持它Pythonic™!

注意:这些跨度也将匹配:;<=>?@',如果您怀疑可能会给您误报,请不要使用快捷方式.(感谢Oliver Aubert在评论中指出这一点.)


所以不要使用上面提到的代码,除非你想考虑:=>;?<;: - <@ =: - @ =; = - @; @: - > == @?> =:?= @; 作为有效的UUID :-)
[0-F]确实匹配0-9和AF,但也包括ASCII码在57(对于9)和65(对于A)之间的任何字符,也就是说:; <=>?@'.

9> pix0r..:

根据定义,UUID是32个十六进制数字,按连字符分为5组,正如您所描述的那样.你的正则表达式不应该错过任何一个.

http://en.wikipedia.org/wiki/Uuid#Definition



10> Christopher ..:

所以,我认为Richard Bronosky实际上拥有迄今为止最好的答案,但我认为你可以做一些让它更简单(或者至少更简洁):

re_uuid = re.compile(r'[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}', re.I)



11> Anton K..:

C ++的变体:

#include   // Required include

...

// Source string    
std::wstring srcStr = L"String with GIUD: {4d36e96e-e325-11ce-bfc1-08002be10318} any text";

// Regex and match
std::wsmatch match;
std::wregex rx(L"(\\{[A-F0-9]{8}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{12}\\})", std::regex_constants::icase);

// Search
std::regex_search(srcStr, match, rx);

// Result
std::wstring strGUID       = match[1];



12> Quanlong..:

对于在OS X上使用生成的UUID uuidgen,正则表达式为

[A-F0-9]{8}-[A-F0-9]{4}-4[A-F0-9]{3}-[89AB][A-F0-9]{3}-[A-F0-9]{12}

验证

uuidgen | grep -E "[A-F0-9]{8}-[A-F0-9]{4}-4[A-F0-9]{3}-[89AB][A-F0-9]{3}-[A-F0-9]{12}"

推荐阅读
ERIK又
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有