Як перевірити, чи містить змінна дійсний ідентифікатор UUID / GUID?
На даний момент мене цікавлять лише перевірки типів 1 і 4, але це не повинно бути обмеженням ваших відповідей.
Як перевірити, чи містить змінна дійсний ідентифікатор UUID / GUID?
На даний момент мене цікавлять лише перевірки типів 1 і 4, але це не повинно бути обмеженням ваших відповідей.
Відповіді:
В даний час 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
[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}
регекс на допомогу
/^[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}\}?$/
/^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/i
Якщо ви хочете перевірити або підтвердити певну версію 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
Якщо ви використовуєте 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
Окрім відповіді Гамбола, яка виконає цю роботу майже у всіх випадках , усі наведені відповіді поки що пропущені, що згруповане форматування (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}}?
Усі викладені до цього часу специфічні для регексу типи не працюють на "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
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
Я думаю , що відповідь Гамбола майже досконала, але вона неправильно трактує 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)
Використовуйте метод .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}$");
}
Трохи модифікована версія вищезазначених відповідей написана більш стисло. Це підтвердить будь-який 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 рази
A-f
має бути A-F
так:/^([0-9a-fA-F]{8})-(([0-9a-fA-F]{4}\-){3})([0-9a-fA-F]{12})$/i
Хороший спосіб зробити це в 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
Я думаю, що кращим способом є використання статичного методу 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