Как проверить действительный UUID / GUID?

271

Как проверить, содержит ли переменная действительный идентификатор UUID / GUID?

В настоящее время меня интересует только проверка типов 1 и 4, но это не должно быть ограничением ваших ответов.

Марек Себера
источник
в строковом формате, а не в шестнадцатеричном, не в мусорном ведре, или я не знаю, что вы просите
Марек Себера
^ (\ {) {0,1} [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} (\}) {0,1} $
Брэндон Морец
Если вы не можете исключить переменные, содержащие цепочку из 32 последовательных шестнадцатеричных цифр (без группировки), взгляните на мой ответ
Wolf

Ответы:

414

В настоящее время UUID соответствуют указанным в RFC4122. Часто забытый крайний случай - NIL UUID, отмеченный здесь . Следующее регулярное выражение учитывает это и возвращает совпадение для NIL UUID. См. Ниже UUID, который принимает только не-NIL UUID. Оба эти решения предназначены для версий с 1 по 5 (см. Первый символ третьего блока).

Поэтому, чтобы проверить UUID ...

/^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i

... гарантирует, что у вас есть канонически отформатированный UUID версии 1-5 и соответствующий вариант согласно RFC4122.

ПРИМЕЧАНИЕ: брекеты {и }не являются каноническими. Они являются артефактом некоторых систем и обычаев.

Легко изменить приведенное выше регулярное выражение, чтобы удовлетворить требования исходного вопроса.

СОВЕТ: регулярное выражение группы / захватывает

Чтобы избежать совпадения NIL UUID:

/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
порезвиться
источник
9
+1 За упоминание Инженерной рабочей группы
mate64
1
Я думаю [1-5] [0-9a-f] {3} неверно. У меня есть действительный UUID, который имеет "b06a" в этой части, и это не удалось для меня.
Фелипе Брам
1
@FelipeBrahm, [1-5] правильно согласно RFC, что 4 бита указывают версию, а есть только 5 версий.
rvignacio
749d0000-0194-1005-2e05-08d61613bf2f терпит неудачу для меня в скрипке
грабит
1
Из любопытства (почему) следующее тоже не будет действительным: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}
tjeerdnet
58

регулярное выражение на помощь

/^[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}$/.test('01234567-9ABC-DEF0-1234-56789ABCDEF0');

или с кронштейнами

/^\{?[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}‌​\}?$/
ryanb
источник
3
или если у вас есть квадратные скобки: / ^ \ {? [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} \} $ / тест ( '01234567-9ABC-DEF0-1234-56789ABCDEF0')?.;
ryanb
Это не совсем правильно. пропускается, что [1-5] (версия) запускает 3-й блок, а [89AB] (вариант) запускает 4-й блок. Ответ Гамбола делает это правильно.
Вольф
7
Более краткая версия (игнорируя скобки):/^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/i
c24w
41

Если вы хотите проверить или проверить конкретную версию 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
Иван Габриэле
источник
39

Если вы используете Node.js для разработки, рекомендуется использовать пакет под названием Validator. Он включает в себя все регулярные выражения, необходимые для проверки различных версий UUID, плюс вы получаете различные другие функции для проверки.

Вот ссылка npm: Validator

var a = 'd3aa88e2-c754-41e0-8ba6-4198a34aa0a2'
v.isUUID(a)
true
v.isUUID('abc')
false
v.isNull(a)
false
Нирадж Шарма
источник
Интересно, а выглядит ли это как дефис? Вот четыре регулярных выражения, которые он в настоящее время использует - /^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i и / или /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i и / или /^[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}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i
ruffin
1
Валидатор поддерживает только UUID v3-5, а не v1
peteb
13

Кроме ответа Гамбола, который будет выполнять работу почти во всех случаях , все ответы, представленные до сих пор, пропустили, что групповое форматирование (8-4-4-4-12) не является обязательным для кодирования GUID в тексте . Он используется очень часто, но, очевидно, допустима также простая цепочка из 32 шестнадцатеричных цифр. [1] регулярное выражение ENH :

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

[1] Речь идет о регистрации ING переменной s, поэтому мы должны включить пользователь недружественной формы , а также.

волк
источник
Это мой любимый. Еще лучше{?[0-9a-f]{8}-?[0-9a-f]{4}-?[1-5][0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}}?
Майк Нельсон
10

Все приведенные к настоящему времени типовые регулярные выражения не работают с нулевым UUID типа 0, определенным в 4.1.7 RFC:

UUID nil - это специальная форма UUID, в которой все 128 бит установлены на ноль: 00000000-0000-0000-0000-000000000000

Чтобы изменить ответ Вольфа:

/^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-5][0-9a-f]{3}-?[089ab][0-9a-f]{3}-?[0-9a-f]{12}$/i

Или, чтобы правильно исключить «тип 0» без всех нулей, у нас есть следующее (спасибо Люку):

/^(?:[0-9a-f]{8}-?[0-9a-f]{4}-?[1-5][0-9a-f]{3}-?[89ab][0-9a‌​-f]{3}-?[0-9a-f]{12}‌​|00000000-0000-0000-‌​0000-000000000000)$/‌​i
Эван Эдвардс
источник
Первый UUID-сегмент нулевого UUID должен иметь 8 нулей, а не 7. Предоставленное регулярное выражение не проверяет его с помощью 7.
Rich Seviora
2
Ваш выглядит лучше, но допускает некоторые недействительные UUID, например: abcdef00-0000-0000-0000-000000000000 будет соответствовать вашему регулярному выражению. Это регулярное выражение будет соответствовать действительным UUID, включая ноль:/^(?:[0-9a-f]{8}-?[0-9a-f]{4}-?[1-5][0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i
Люк
10

благодаря @usertatha с некоторыми изменениями

function isUUID ( uuid ) {
    let s = "" + uuid;

    s = s.match('^[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}$');
    if (s === null) {
      return false;
    }
    return true;
}
Souhaieb
источник
2

Я думаю, что ответ Гамбола почти идеален, но он неверно истолковывает RFC 4122 § 4.1.1. Вариант раздела немного.

Он охватывает варианты UUID варианта 1 (10xx = 8..b), но не охватывает варианты варианта 0 (0xxx = 0,7) и варианта 2 (110x = c..d), которые зарезервированы для обратной совместимости, поэтому они являются технически действительными UUID. Вариант-4 (111x = e..f) действительно зарезервирован для будущего использования, поэтому в настоящее время он недействителен.

Кроме того, тип 0 недопустим, эта цифра может быть только 0, если это NIL UUID (как упомянуто в ответе Эвана ).

Поэтому я думаю, что наиболее точное регулярное выражение, соответствующее текущей спецификации RFC 4122, (включая дефисы):

/^([0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[0-9a-d][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i
                            ^                ^^^^^^
                    (0 type is not valid)  (only e..f variant digit is invalid currently)
Б. Золи
источник
1

Используйте метод .match (), чтобы проверить, является ли String UUID.

public boolean isUUID(String s){
    return s.match("^[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}$");
}
userTatha
источник
Uncaught TypeError: s.matches не является функцией
Deep Kakkar
1
Данный скрипт не является Javascript, о котором просит OP.
StefanJanssen
Скорректированный ответ с учетом комментариев выше. Решение теперь работает, как и ожидалось.
DeeZone
Это все еще не JS.
ktilcu
1

Слегка измененная версия приведенных выше ответов написана более лаконично. Это проверит любой GUID с дефисами (однако его легко изменить, чтобы сделать дефис необязательным). Это также будет поддерживать символы верхнего и нижнего регистра, которые стали соглашением независимо от спецификации:

/^([0-9a-fA-F]{8})-(([0-9a-fA-F]{4}\-){3})([0-9a-fA-F]{12})$/i

Ключ здесь - повторяющаяся часть ниже

(([0-9a-fA-F]{4}\-){3})

Который просто повторяет 4 паттерна 3 символа

Джеймс Моррисон
источник
1
A-fдолжно быть A-Fтак:/^([0-9a-fA-F]{8})-(([0-9a-fA-F]{4}\-){3})([0-9a-fA-F]{12})$/i
DeeZone
если вы используете случай (/ i), зачем повторять af, а затем AF?
Нимрод
0

Хороший способ сделать это в Node - использовать ajvпакет ( https://github.com/epoberezkin/ajv ).

const Ajv = require('ajv');
const ajv = new Ajv({ allErrors: true, useDefault: true, verbose: true });
const uuidSchema = { type: 'string', format: 'uuid' };
ajv.validate(uuidSchema, 'bogus'); // returns false
ajv.validate(uuidSchema, 'd42a8273-a4fe-4eb2-b4ee-c1fc57eb9865'); // returns true with v4 GUID
ajv.validate(uuidSchema, '892717ce-3bd8-11ea-b77f-2e728ce88125'); // returns true with a v1 GUID
blackcatweb
источник
-1

Я думаю, что лучше использовать статический метод fromString, чтобы избежать этих регулярных выражений.

    id = UUID.randomUUID();
    UUID uuid = UUID.fromString(id.toString());
    Assert.assertEquals(id.toString(), uuid.toString());

С другой стороны

   UUID uuidFalse = UUID.fromString("x");

throws java.lang.IllegalArgumentException: Неверная строка UUID: x

Вернер Дивишек
источник