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

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

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

Я согласен, что по определению ваше регулярное выражение не пропускает 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}}" 

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

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

@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 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}/ 

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

Обратите внимание, что единственное различие – номер версии , который объясняется в 4.1.3. Version 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 
 /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89AB][0-9a-f]{3}-[0-9a-f]{12}$/i 

Регулярное выражение Gajus отклоняет UUID V1-3 и 5, хотя они действительны.

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

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

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

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

В 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, чтобы сравнить их эффективность.

Наслаждаться. Держите его Pythonic ™!

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

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

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

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

 #include  // 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, сгенерированного в 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}" 
 $UUID_RE = join '-', map { "[0-9a-z]{$_}" } 8, 4, 4, 4, 12; 

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

  • Какое регулярное выражение никогда не будет соответствовать?
  • Что значит ?! имею в виду?
  • Regex: Согласование путем исключения, без надежды - возможно ли это?
  • Regex для разделения HTML-тегов
  • Регулярное выражение противоположно
  • Regex: все, кроме
  • Как отменить все регулярное выражение?
  • Regex - Должны ли экраны сбрасываться?
  • Как сопоставить любой символ в нескольких строках в регулярном выражении?
  • Регулярное выражение для пропуска символа в группе захвата
  • Получить окончательный специальный символ с регулярным выражением
  • Давайте будем гением компьютера.