Поиск UUID в тексте с регулярным выражением

Я ищу UUID в блоках текста, используя регулярное выражение. В настоящее время я полагаюсь на предположение, что все UUID будут следовать за указателем 8-4-4-4-12 шестнадцатеричных цифр.

Может ли кто-нибудь подумать о прецеденте, когда это предположение было бы недействительным, и может ли я пропустить некоторые UUID?

Ответ 1

Я согласен, что по определению ваше регулярное выражение не пропускает никакого UUID. Однако может быть полезно отметить, что если вы ищете особенно для глобальных уникальных идентификаторов Microsoft (GUID), существует пять эквивалентных представлений строк для 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}}" 

Ответ 2

Регулярное выражение для uuid:

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

Ответ 3

@ivelin: UUID может иметь капители. Таким образом, вам понадобится toLowerCase() строка или использовать:

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

Было бы просто прокомментировать это, но недостаточно rep:)

Ответ 4

Версии 4 UUID имеют форму xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx, где x - любая шестнадцатеричная цифра, а y - одна из 8, 9, A или B. например. f47ac10b-58cc-4372-a567-0e02b2c3d479.

источник: http://en.wikipedia.org/wiki/Uuid#Definition

Поэтому это технически более корректно:

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

Ответ 5

Если вы хотите проверить или проверить конкретную версию UUID, вот соответствующие регулярные выражения.

Обратите внимание, что единственное различие - номер версии, который объясняется в главе 4.1.3. Version UUID 4122 RFC.

Номер версии - это первый символ третьей группы: [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
    

Ответ 6

Это то же самое, что и @Ivelin, но короче:

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

regexp Gajus отклоняет UUID V1-3 и 5, хотя они действительны.

Ответ 7

[\w]{8}(-[\w]{4}){3}-[\w]{12} работал у меня в большинстве случаев.

Или, если вы хотите быть действительно конкретным [\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12}.

Ответ 8

По определению UUID представляет собой 32 шестнадцатеричных цифры, разделенных в 5 группах дефисом, как вы описали. Вы не должны упускать из виду свое регулярное выражение.

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

Ответ 9

В python re вы можете переходить от числовой к альфа-версии верхнего регистра. Так..

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

Это делает простейшее регулярное выражение UUID Python:

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

Я оставлю это как упражнение для чтения, чтобы использовать timeit для сравнения производительности.

Enjoy. Держите его Pythonic ™!

ПРИМЕЧАНИЕ: Эти интервалы также будут соответствовать :;<=>[email protected]', поэтому, если вы подозреваете, что могли бы дать вам ложные срабатывания, не используйте ярлык. (Спасибо, Оливер Обер, за то, что указали это в комментариях.)

Ответ 10

Итак, я думаю, что у Ричарда Броноски на самом деле есть лучший ответ на сегодняшний день, но я думаю, что вы можете немного сделать его несколько проще (или, по крайней мере, терпение):

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

Ответ 11

Для UUID, сгенерированного в OS X с uuidgen, шаблон регулярного выражения

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

Проверить с помощью

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

Ответ 12

Вариант для С++:

#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];

Ответ 13

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

BTW, разрешая только 4 на одной из позиций, действителен только для UUIDv4. Но v4 - не единственная версия UUID, которая существует. Я также встречал v1 в своей практике.