Je recherche des UUID dans des blocs de texte à l'aide d'une expression rationnelle. Actuellement, je m'appuie sur l'hypothèse que tous les UUID suivront un modèle de 8-4-4-4-12 chiffres hexadécimaux.
Quelqu'un peut-il penser à un cas d'utilisation où cette hypothèse serait invalide et me ferait perdre des UUID?
Je conviens que, par définition, votre expression rationnelle ne manque aucun UUID. Toutefois, il peut être utile de noter que si vous recherchez en particulier des identificateurs globaux uniques (GUID) de Microsoft, il existe cinq représentations de chaîne équivalentes pour 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 regex pour uuid est:
\b[0-9a-f]{8}\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\b[0-9a-f]{12}\b
@ivelin: UUID peut avoir des majuscules. Vous devrez donc soit toLowerCase () la chaîne, soit utiliser:
[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}
J'aurais juste commenté ceci mais pas assez de rep :)
Les UUID de la version 4 ont la forme xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx où x est un chiffre hexadécimal et y un des 8, 9, A ou B. par exemple. f47ac10b-58cc-4372-a567-0e02b2c3d479.
source: http://en.wikipedia.org/wiki/Uuid#Definition
C'est donc techniquement plus correct:
/[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}/
Si vous souhaitez vérifier ou valider une version spécifique de l'UUID , voici les expressions rationnelles correspondantes.
Notez que la seule différence est le numéro de version , expliqué dans le chapitre
4.1.3. Version
de ID 4122 RFC .
Le numéro de version est le premier caractère du troisième groupe: [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
Les expressions rationnelles de Gajus rejettent les UUID V1-3 et 5, même s'ils sont valides.
[\w]{8}(-[\w]{4}){3}-[\w]{12}
a fonctionné pour moi dans la plupart des cas.
Ou si vous voulez être vraiment spécifique [\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12}
.
Par définition, un UUID est composé de 32 chiffres hexadécimaux, séparés en 5 groupes par des traits d'union, comme vous l'avez décrit. Vous ne devriez pas en manquer avec votre expression habituelle.
Dans python re, vous pouvez étendre l'alpha numérique en majuscule. Alors..
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']
Cela simplifie la regex Python UUID:
re_uuid = re.compile("[0-F]{8}-([0-F]{4}-){3}[0-F]{12}", re.I)
Je laisserai au lecteur le soin d’utiliser le temps pour comparer les performances de ceux-ci.
Prendre plaisir. Continuez comme ça Pythonic ™!
NOTE: Ces étendues correspondront également à :;<=>?@'
donc si vous pensez que cela pourrait vous donner de faux positifs, ne prenez pas le raccourci. (Merci, Oliver Aubert, de l'avoir signalé dans les commentaires.)
Donc, je pense que Richard Bronosky a la meilleure réponse à ce jour, mais je pense que vous pouvez faire un peu pour le rendre un peu plus simple (ou au moins terser):
re_uuid = re.compile(r'[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}', re.I)
Pour les UUID générés sous OS X avec uuidgen
, le motif de regex est
[A-F0-9]{8}-[A-F0-9]{4}-4[A-F0-9]{3}-[89AB][A-F0-9]{3}-[A-F0-9]{12}
Vérifier avec
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}"
Variante pour 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];
$UUID_RE = join '-', map { "[0-9a-f]{$_}" } 8, 4, 4, 4, 12;
BTW, autoriser seulement 4 sur l’une des positions n’est valable que pour UUIDv4. Mais la v4 n'est pas la seule version d'UUID existante. J'ai rencontré v1 dans ma pratique aussi.