Як перевірити дійсні UUID / GUID?


270

Як перевірити, чи містить змінна дійсний ідентифікатор UUID / GUID?

На даний момент мене цікавлять лише перевірки типів 1 і 4, але це не повинно бути обмеженням ваших відповідей.


у рядковому форматі, а не шістнадцятковий, не бін, або я не знаю, що ви просите
Marek Sebera

^ (\ {) {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-х послідовних шістнадцяткових цифр (без групування), погляньте на мою відповідь
Вовк

Відповіді:


413

В даний час 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


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}‌​\}?$/

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
коротка

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: Валідатор

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

Усі викладені до цього часу специфічні для регексу типи не працюють на "Nil UUID" типу 0 ", визначеному в 4.1.7 RFC як:

Нульовий UUID - це особлива форма 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.
Наданий

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

2

Я думаю , що відповідь Гамбола майже досконала, але вона неправильно трактує RFC 4122 § 4.1.1. Варіант розділу трохи.

Він охоплює UUID з варіантами 1 (10xx = 8..b), але не охоплює варіанти Variant-0 (0xxx = 0..7) та Variant-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}$");
}

Uncaught TypeError: s.matches - це не функція
Deep Kakkar

1
Даний скрипт - це не Javascript, про що вимагає ОП.
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

-1

Я думаю, що кращим способом є використання статичного методу fromString, щоб уникнути цих регулярних виразів.

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

З іншої сторони

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

кидає java.lang.IllegalArgumentException: Недійсний рядок UUID: x

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.