Búsqueda de UUID en texto con expresiones regulares

Estoy buscando UUID en bloques de texto usando una expresión regular. Actualmente estoy confiando en la suposición de que todos los UUID seguirán una paleta de 8-4-4-4-12 dígitos hexadecimales.

¿Alguien puede pensar en un caso de uso donde esta suposición sería inválida y me haría perder algunos UUID?

Estoy de acuerdo en que, por definición, su expresión regular no pierde ningún UUID. Sin embargo, puede ser útil tener en cuenta que si está buscando especialmente los Identificadores únicos globales de Microsoft (GUID), existen cinco representaciones de cadenas equivalentes para un 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}}" 

La expresión regular para uuid es:

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

@ivelin: UUID puede tener mayúsculas. Entonces necesitarás toLowerCase () la cadena o usar:

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

Hubiera comentado esto pero no suficiente representante 🙂

Los UUID de versión 4 tienen el formato xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx donde x es cualquier dígito hexadecimal e y es uno de 8, 9, A o B. eg f47ac10b-58cc-4372-a567-0e02b2c3d479.

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

Por lo tanto, esto es técnicamente más correcto:

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

Si desea verificar o validar una versión de UUID específica , aquí están las expresiones regulares correspondientes.

Tenga en cuenta que la única diferencia es el número de versión , que se explica en 4.1.3. Version Capítulo de 4.1.3. Version de UUID 4122 RFC .

El número de versión es el primer personaje del tercer grupo: [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 
 /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89AB][0-9a-f]{3}-[0-9a-f]{12}$/i 

La expresión regular de Gajus rechaza los UUID V1-3 y 5, aunque son válidos.

[\w]{8}(-[\w]{4}){3}-[\w]{12} ha funcionado en la mayoría de los casos.

O si quiere ser realmente específico [\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12} .

Por definición, un UUID es de 32 dígitos hexadecimales, separados en 5 grupos por guiones, tal como lo ha descrito. No debes perder ninguno con tu expresión regular.

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

En python re, puede abarcar desde alfa numérica a mayúscula. Asi que..

 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'] 

Eso hace que la expresión regular de UUID de Python sea más simple:

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

Lo dejaré como ejercicio para que el lector use el tiempo para comparar el rendimiento de estos.

Disfrutar. ¡Manténgalo Pythonic ™!

NOTA: Esos espacios también coincidirán :;<=>?@' lo que, si sospecha que podría proporcionarle falsos positivos, no tome el atajo. (Gracias Oliver Aubert por señalarlo en los comentarios).

Entonces, creo que Richard Bronosky realmente tiene la mejor respuesta hasta la fecha, pero creo que puedes hacer un poco para que sea algo más simple (o al menos terser):

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

Variante para 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]; 

Para UUID generado en OS X con uuidgen , el patrón de uuidgen regulares es

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

Verificar con

 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; 

Por cierto, permitir solo 4 en una de las posiciones solo es válido para UUIDv4. Pero v4 no es la única versión de UUID que existe. Me he encontrado con v1 en mi práctica también.