使用正则expression式在文本中searchUUID

我正在使用正则expression式在文本块中searchUUID。 目前我所依赖的假设是所有的UUID都将遵循8-4-4-4-12hex数字的格式。

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

我同意你的正则expression式不会错过任何UUID。 但是,请注意,如果特别searchMicrosoft的全局唯一标识符(GUID),则可能有以下五种等效的GUID表示forms:

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

uuid的正则expression式是:

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

@ivelin:UUID可以有首都。 所以你要么需要toLowerCase()string或使用:

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

会刚刚评论这个,但没有足够的代表:)

版本4UUID具有xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxxforms,其中x是任何hex数字,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}/ 

如果您想检查或validation特定的UUID版本 ,则这里是相应的正则expression式。

请注意, 唯一的区别是版本号 ,在4.1.3. Version解释4.1.3. Version 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 

这与Ivelin的答案是一样的,但是更短:

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

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

按照定义,UUID是32个hex数字,用连字符分隔成5组,正如你所描述的那样。 你不应该错过任何你的正则expression式。

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

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

或者,如果你想具体说明[\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12}

在Python中,你可以跨越从数字到大写字母。 所以..

 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正则expression式:

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

我将把它作为一个练习给读者使用timeit来比较这些performance。

请享用。 保持Pythonic™!

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

所以,我认为理查德·布罗诺斯基(Richard Bronosky)实际上有最好的答案,但是我认为你可以做一些简单的工作(或者至less比较简单):

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

C ++的变体:

 #include <regex> // 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]; 

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

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

validation

 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}" 
 $UUID_RE = join '-', map { "[0-9a-z]{$_}" } 8, 4, 4, 4, 12; 

顺便说一句,只允许其中一个职位只有4对UUIDv4有效。 但是v4并不是唯一的UUID版本。 我在练习中遇到了v1。