Jak sprawdzić, czy zmienna zawiera prawidłowy identyfikator UUID / GUID?
Obecnie jestem zainteresowany tylko sprawdzaniem poprawności typów 1 i 4, ale nie powinno to stanowić ograniczenia dla twoich odpowiedzi.
Jak sprawdzić, czy zmienna zawiera prawidłowy identyfikator UUID / GUID?
Obecnie jestem zainteresowany tylko sprawdzaniem poprawności typów 1 i 4, ale nie powinno to stanowić ograniczenia dla twoich odpowiedzi.
Odpowiedzi:
Obecnie identyfikatory UUID są określone w RFC4122. Często pomijanym przypadkiem na krawędzi jest NIL UUID, odnotowany tutaj . Poniższy wyrażenie regularne bierze to pod uwagę i zwróci dopasowanie dla UUID NIL. Zobacz poniżej UUID, który akceptuje tylko UUID inne niż NIL. Oba rozwiązania dotyczą wersji od 1 do 5 (patrz pierwszy znak trzeciego bloku).
Dlatego, aby sprawdzić poprawność 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
... zapewnia, że masz kanonicznie sformatowany identyfikator UUID, który jest w wersji od 1 do 5 i jest odpowiednią wersją zgodnie z RFC4122.
UWAGA: Szelki {
i }
nie są kanoniczne. Są artefaktem niektórych systemów i zastosowań.
Łatwo zmodyfikować powyższe wyrażenie regularne, aby spełnić wymagania pierwotnego pytania.
WSKAZÓWKA: regex group / capture
Aby uniknąć dopasowania 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}
regex na ratunek
/^[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');
lub w nawiasach
/^\{?[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
Jeśli chcesz sprawdzić lub sprawdzić konkretną wersję UUID, oto odpowiednie wyrażenia regularne.
Zauważ, że jedyną różnicą jest numer wersji , który wyjaśniono w
4.1.3. Version
rozdziale UUID 4122 RFC .
Numer wersji to pierwszy znak trzeciej grupy [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
Jeśli używasz Node.js do programowania, zaleca się użycie pakietu o nazwie Validator. Zawiera wszystkie wyrażenia regularne wymagane do sprawdzania poprawności różnych wersji UUID oraz różne inne funkcje do sprawdzania poprawności.
Oto link 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
i / lub /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i
i / lub /^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i
i / lub /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i
Oprócz odpowiedzi Gambol, która wykona zadanie w prawie wszystkich przypadkach , wszystkie dotychczas udzielone odpowiedzi pominęły, że zgrupowane formatowanie (8-4-4-4-12) nie jest obowiązkowe do kodowania GUID w tekście . Jest używany bardzo często, ale oczywiście poprawny może być również zwykły łańcuch 32 cyfr szesnastkowych. [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] Chodzi o to o sprawdzenie ing zmienna s, więc należy zaliczyć kształt nieprzyjazny dla użytkownika, jak również.
{?[0-9a-f]{8}-?[0-9a-f]{4}-?[1-5][0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}}?
Wszystkie opublikowane wcześniej wyrażenia specyficzne dla typu kończą się niepowodzeniem na UUID „zero 0”, zdefiniowanym w 4.1.7 RFC, jako:
Zero UUID jest specjalną formą UUID, która została określona tak, aby wszystkie 128 bitów było ustawione na zero:
00000000-0000-0000-0000-000000000000
Aby zmodyfikować odpowiedź Wolfa:
/^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-5][0-9a-f]{3}-?[089ab][0-9a-f]{3}-?[0-9a-f]{12}$/i
Lub, aby poprawnie wykluczyć „typ 0” bez wszystkich zer, mamy następujące (dzięki Łukaszowi):
/^(?:[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
pasuje do wyrażenia regularnego. Ta regex będzie pasować do prawidłowych UUID, w tym zero:/^(?:[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
Myślę, że odpowiedź Gambola jest prawie idealna, ale źle interpretuje RFC 4122 § 4.1.1. Część wariantu trochę.
Obejmuje UUID wariantu 1 (10xx = 8..b), ale nie obejmuje wariantów wariantu 0 (0xxx = 0..7) i wariantu 2 (110x = c..d), które są zarezerwowane dla kompatybilności wstecznej, więc są technicznie poprawnymi identyfikatorami UUID. Wariant 4 (111x = e..f) jest rzeczywiście zarezerwowany do wykorzystania w przyszłości, więc obecnie nie są one ważne.
Ponadto typ 0 jest niepoprawny, ta „cyfra” może być równa 0, jeśli jest to NU UUID (jak wspomniano w odpowiedzi Evana ).
Myślę więc, że najdokładniejszym wyrażeniem regularnym zgodnym z aktualną specyfikacją RFC 4122 jest (w tym łączniki):
/^([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)
Użyj metody .match (), aby sprawdzić, czy String jest 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}$");
}
Nieco zmodyfikowana wersja powyższych odpowiedzi napisana w bardziej zwięzły sposób. Spowoduje to sprawdzenie poprawności dowolnego identyfikatora GUID z łącznikami (bez względu na łatwość modyfikacji, tak aby łączniki były opcjonalne). Będzie to również obsługiwać wielkie i małe litery, które stały się konwencją niezależnie od specyfikacji:
/^([0-9a-fA-F]{8})-(([0-9a-fA-F]{4}\-){3})([0-9a-fA-F]{12})$/i
Kluczem tutaj jest powtarzająca się część poniżej
(([0-9a-fA-F]{4}\-){3})
Który po prostu powtarza 4 wzorce znaków 3 razy
A-f
powinno być A-F
tak:/^([0-9a-fA-F]{8})-(([0-9a-fA-F]{4}\-){3})([0-9a-fA-F]{12})$/i
Dobrym sposobem na zrobienie tego w węźle jest użycie ajv
pakietu ( 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
Myślę, że lepszym sposobem jest użycie metody statycznej fromString, aby uniknąć tych wyrażeń regularnych.
id = UUID.randomUUID();
UUID uuid = UUID.fromString(id.toString());
Assert.assertEquals(id.toString(), uuid.toString());
Z drugiej strony
UUID uuidFalse = UUID.fromString("x");
wyrzuca java.lang.IllegalArgumentException: Niepoprawny ciąg UUID: x