regex - probar - Búsqueda de UUID en texto con expresiones regulares
regex ejemplos (13)
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?
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}/
@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 :)
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)
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}
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}"
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.
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 de4.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
Variante para 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];
[/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}
.
$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.
/^[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.