web-dev-qa-db-fra.com

Recherche d'UUID dans le texte avec regex

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?

197
Guy

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

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
417
Ivelin

@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 :)

112
Matthew F. Robben

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}/
103
Gajus

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
    
76
Ivan Gabriele
/^[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.

33
iGEL

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

14
JimP

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.

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

10
pix0r

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.)

10
Bruno Bronosky

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)
6
Christopher Smith

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

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];
5
Anton K
$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.

2
abufct