Zoeken naar UUID’s in tekst met regex

Ik zoek naar UUID’s in tekstblokken met een regex. Momenteel vertrouw ik op de veronderstelling dat alle UUID’s een patroon van 8-4-4-4-12 hexadecimale cijfers zullen volgen.

Kan iemand een gebruiksscenario bedenken waarbij deze veronderstelling ongeldig zou zijn en ervoor zou zorgen dat ik enkele UUID’s zou missen?


Antwoord 1, autoriteit 100%

Ik ben het ermee eens dat je regex per definitie geen UUID mist. Het kan echter handig zijn om op te merken dat als u speciaal zoekt naar de Globally Unique Identifiers (GUID’s) van Microsoft, er vijf equivalente tekenreeksrepresentaties zijn voor een 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}}" 

Antwoord 2, autoriteit 94%

De regex voor uuid is:

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

Antwoord 3, autoriteit 95%

@ivelin: UUID kan hoofdletters hebben. U moet dus ofwel de string toLowerCase() gebruiken of:

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

Zou hier net een opmerking over hebben gemaakt, maar niet genoeg rep 🙂


Antwoord 4, autoriteit 94%

Versie 4 UUID’s hebben de vorm xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx waarbij x een hexadecimaal cijfer is en y een van 8, 9, A of B is. b.v. f47ac10b-58cc-4372-a567-0e02b2c3d479.

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

Daarom is dit technisch correcter:

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

Antwoord 5, autoriteit 263%

Als u een specifieke UUID-versiewilt controleren of valideren, vindt u hier de bijbehorende regexes.

Merk op dat het enige verschil het versienummeris, dat wordt uitgelegd in 4.1.3. Versionhoofdstuk van UUID 4122 RFC.

Het versienummer is het eerste teken van de derde groep : [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
    

Antwoord 6, autoriteit 93%

/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89AB][0-9a-f]{3}-[0-9a-f]{12}$/i

De regexp van Gajus verwerpt UUID V1-3 en 5, ook al zijn ze geldig.


Antwoord 7, autoriteit 47%

[\w]{8}(-[\w]{4}){3}-[\w]{12}heeft in de meeste gevallen voor mij gewerkt.

Of als je echt specifiek wilt zijn [\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12}.


Antwoord 8, autoriteit 26%

In python re kun je variëren van numeriek tot hoofdletters alfa. Dus..

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

Dat maakt de eenvoudigste Python UUID-regex:

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

Ik laat het als een oefening aan de lezer over om timeit te gebruiken om de prestaties hiervan te vergelijken.

Geniet.
Houd het Pythonic™!

OPMERKING:die bereiken komen ook overeen met :;<=>?@'dus als u vermoedt dat dit u valse positieven kan opleveren, neem dan geen de snelkoppeling. (Bedankt Oliver Aubert dat je erop hebt gewezen in de opmerkingen.)


Antwoord 9, autoriteit 21%

Per definitie is een UUID 32 hexadecimale cijfers, gescheiden in 5 groepen door koppelteken, net zoals u hebt beschreven. Moet je er geen missen met je reguliere expressie.

http://en.wikipedia.org/wiki/uuid#definition


Antwoord 10, Autoriteit 16%

Dus, ik denk dat Richard Bronosky eigenlijk het beste antwoord heeft, maar ik denk dat je een beetje kunt doen om het enigszins eenvoudiger te maken (of tenminste TERSER):

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

Antwoord 11, Autoriteit 14%

Variant voor 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];

Antwoord 12, Autoriteit 14%

Voor UUID gegenereerd op OS X met uuidgen, is het Regex-patroon

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

verifiëren met

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

Antwoord 13, Autoriteit 12%

Hier is het werk Regex: https://www.regextester.com/99148

const regex = [0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}

Antwoord 14, autoriteit 7%

$UUID_RE = join '-', map { "[0-9a-f]{$_}" } 8, 4, 4, 4, 12;

BTW, het toestaan van slechts 4 op een van de posities is alleen geldig voor UUIDv4.
Maar v4 is niet de enige UUID-versie die bestaat.
Ik heb v1 ook in mijn praktijk ontmoet.


Antwoord 15, autoriteit 7%

Als u Posix regex (grep -E, MySQL, enz.) gebruikt, is dit wellicht gemakkelijker te lezen & onthoud:

[[:xdigit:]]{8}(-[[:xdigit:]]{4}){3}-[[:xdigit:]]{12}

Bewerken:Perl & PCRE-smaken ondersteunen ook Posix-tekenklassen, dus dit zal met hen werken. Wijzig hiervoor de (…)in een niet-vastleggende subgroep (?:…).


Antwoord 16, autoriteit 5%

Voor bash:

grep -E "[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}"

Bijvoorbeeld:

$> echo "f2575e6a-9bce-49e7-ae7c-bff6b555bda4" | grep -E "[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}"
f2575e6a-9bce-49e7-ae7c-bff6b555bda4

Antwoord 17

Ik wilde mijn bijdrage leveren, aangezien mijn regex alle gevallen van OP dekt en alle relevante gegevens correct groepeert op de groepsmethode (je hoeft de string niet te verwerken om elk deel van de uuid te krijgen, deze regex krijgt al het voor jou)

([\d\w]{8})-?([\d\w]{4})-?([\d\w]{4})-?([\d\w]{4})-?([\d\w]{12})|[{0x]*([\d\w]{8})[0x, ]{4}([\d\w]{4})[0x, ]{4}([\d\w]{4})[0x, {]{5}([\d\w]{2})[0x, ]{4}([\d\w]{2})[0x, ]{4}([\d\w]{2})[0x, ]{4}([\d\w]{2})[0x, ]{4}([\d\w]{2})[0x, ]{4}([\d\w]{2})[0x, ]{4}([\d\w]{2})[0x, ]{4}([\d\w]{2})

Other episodes