Geçerli UUID / GUID nasıl test edilir?


270

Değişkenin geçerli UUID / GUID tanımlayıcısı içerip içermediğini nasıl kontrol edebilirim?

Şu anda yalnızca 1 ve 4 tiplerini doğrulamakla ilgileniyorum, ancak cevaplarınız için bir sınırlama olmamalıdır.


string biçiminde, hex değil, bin değil, ya da ne istediğini bilmiyorum
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} $
Brandon Moretz

32 ardışık onaltılık basamaklı bir zincir içeren değişkenleri (gruplama olmadan) hariç
Wolf

Yanıtlar:


413

Şu anda, UUID'ler RFC4122'de belirtildiği gibidir. Sıklıkla ihmal edilen bir uç durum, burada belirtilen NIL UUID'dir . Aşağıdaki normal ifade bunu dikkate alır ve bir NIL UUID için bir eşleşme döndürür. Yalnızca NIL olmayan UUID'leri kabul eden bir UUID için aşağıya bakın. Bu çözümlerin her ikisi de 1 ila 5 sürümleri içindir (üçüncü bloğun ilk karakterine bakın).

Bu nedenle bir UUID'yi doğrulamak için ...

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

... Sürüm 1 ila 5 olan ve RFC4122'ye göre uygun Varyant olan standart olarak biçimlendirilmiş bir UUID'ye sahip olmanızı sağlar.

NOT: Diş telleri {ve }kanonik değildir. Bazı sistemlerin ve kullanımların bir eseridir.

Orijinal sorunun gereksinimlerini karşılamak için yukarıdaki regex değiştirmek kolaydır.

İPUCU: normal ifade grubu / yakalar

NIL UUID ile eşleşmeyi önlemek için:

/^[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
Bence [1-5] [0-9a-f] {3} yanlış. Bu bölümde "b06a" olan geçerli bir UUID var ve bu benim için başarısız oldu.
Felipe Brahm

1
@FelipeBrahm, [1-5] RFC'ye göre doğrudur, 4 bit sürümü gösterir ve sadece 5 sürüm vardır.
rvignacio

749d0000-0194-1005-2e05-08d61613bf2f keman benim için başarısız
çalmaktadır

1
Merak dışında, (neden) aşağıdakiler de geçerli olmaz: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}
tjeerdnet

58

kurtarmaya düzenli

/^[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');

veya braketlerle

/^\{?[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
veya köşeli paranteziniz varsa: / ^ \ {? [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} \} $ / testi ( '01234567-9ABC-DEF0-1234-56789ABCDEF0')?.;
ryanb

Bu pek doğru değil. [1-5] (sürüm) 3. bloğu başlatır ve [89AB] (varyant) 4. bloğu başlatır. Gambol'un cevabı doğru.
Kurt

7
Daha özlü sürüm (parantez yok /^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/i
sayılıyor

41

Belirli bir UUID sürümünü kontrol etmek veya doğrulamak istiyorsanız, ilgili regex'ler aşağıdadır.

Tek farkın, UUID 4122 RFC4.1.3. Version bölümünde açıklanan sürüm numarası olduğuna dikkat edin .

Sürüm numarası üçüncü grubun ilk karakteridir [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

Geliştirme için Node.js kullanıyorsanız, Validator adlı bir paket kullanılması önerilir. UUID'lerin farklı sürümlerini doğrulamak için gereken tüm regex'leri içerir ve ayrıca doğrulama için çeşitli işlevler alırsınız.

İşte npm bağlantısı: Validator

var a = 'd3aa88e2-c754-41e0-8ba6-4198a34aa0a2'
v.isUUID(a)
true
v.isUUID('abc')
false
v.isNull(a)
false

İlginç, ama tireler bekliyor gibi görünüyor? İşte şu anda kullandığı dört regexes - /^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i ve / veya /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i ve / veya /^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i ve / veya /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i
ruffin

1
Doğrulayıcı yalnızca UUID v3-5'i v1'i desteklemez
Peteb

13

Gambol'un hemen hemen her durumda işi yapacak cevabının yanı sıra , şimdiye kadar verilen tüm cevaplar, gruplandırılmış biçimlendirmenin (8-4-4-4-12) metindeki GUID'leri kodlamak için zorunlu olmadığını kaçırdı . Son derece sık kullanılır, ancak açıkçası 32 onaltılık basamaklı düz bir zincir de geçerli olabilir. [1] normal ifade 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] bir soru ile ilgili olan kontrol ing değişken biz de kullanıcı dostu olmayan bir form dahil bu yüzden, s.


Bu benim fave. Daha da iyisi{?[0-9a-f]{8}-?[0-9a-f]{4}-?[1-5][0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}}?
mike nelson

10

Şimdiye kadar yayınlanan tüm türe özgü regex'ler, RFC'nin 4.1.7'sinde tanımlanan "type 0" Nil UUID'de başarısız oluyor:

Nil UUID, 128 bitin hepsinin sıfıra ayarlandığı belirtilen özel UUID biçimidir: 00000000-0000-0000-0000-000000000000

Wolf'un cevabını değiştirmek için:

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

Veya, sıfır olmayan bir "tip 0" ı düzgün bir şekilde hariç tutmak için aşağıdakilere sahibiz (Luke sayesinde):

/^(?:[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

Nil UUID'nin ilk UUID segmenti 7 değil 8 sıfır olmalıdır. Sağlanan normal ifade 7 ile doğrulamamıştır.
Rich Seviora

2
Sevgiler daha hoş görünüyor, ancak bazı geçersiz UUID'lere izin veriyor, örneğin: abcdef00-0000-0000-0000-000000000000 normal ifadenizle eşleşir. Bu normal ifade, nil dahil olmak üzere geçerli UUID'lerle eşleşecek:/^(?:[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
Luke

10

bazı değişiklikler ile @usertatha sayesinde

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

Bence Gambol'un cevabı neredeyse mükemmel, ama RFC 4122 § 4.1.1'i yanlış yorumluyor . Varyant bölümü biraz.

Varyant-1 UUID'leri (10xx = 8..b) kapsar, ancak geriye dönük uyumluluk için ayrılmış Varyant-0 (0xxx = 0..7) ve Varyant-2 (110x = c..d) varyantlarını kapsamaz, dolayısıyla teknik olarak geçerli UUID'lerdir. Varyant-4 (111x = e..f) gerçekten ileride kullanılmak üzere ayrılmıştır, bu nedenle şu anda geçerli değildir.

Ayrıca, 0 türü geçerli değil, "basamak" ın yalnızca bir NIL UUID olması durumunda ( Evan'ın cevabında belirtildiği gibi) 0 olmasına izin verilir .

Bu yüzden mevcut RFC 4122 belirtimine uyan en doğru regex olduğunu düşünüyorum (tireler dahil):

/^([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

Dize'nin UUID olup olmadığını kontrol etmek için .match () yöntemini kullanın.

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}$");
}

Yakalanmayan TypeError: s.matches bir işlev değil
Deep Kakkar

1
Verilen komut dosyası, OP'nin istediği Javascript değil.
StefanJanssen

Yukarıdaki yorumları ele almak için düzeltilmiş cevap. Çözüm artık beklendiği gibi çalışıyor.
DeeZone

Hala js değil.
ktilcu

1

Yukarıdaki cevapların biraz değiştirilmiş bir versiyonu daha özlü bir şekilde yazılmıştır. Bu, herhangi bir GUID'yi kısa çizgilerle doğrular (ancak kısa çizgileri isteğe bağlı yapmak için kolayca değiştirilebilir). Bu, şartnameden bağımsız olarak kural haline gelen büyük ve küçük harfleri de destekleyecektir:

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

Buradaki anahtar aşağıdaki yinelenen kısım

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

Hangi 4 karakter desenini 3 kez tekrarlar


1
A-fşöyle olmalı A-F:/^([0-9a-fA-F]{8})-(([0-9a-fA-F]{4}\-){3})([0-9a-fA-F]{12})$/i
DeeZone

Eğer (/ i) vakası varsa, neden af ​​ve sonra AF'yi tekrarlıyorsunuz?
Nemrut

0

Düğümde yapmanın iyi bir yolu ajvpaketi kullanmaktır ( 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

Daha iyi bir yol bu düzenli ifadeleri önlemek için fromString statik yöntemini kullanmak olduğunu düşünüyorum.

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

Diğer yandan

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

throws java.lang.IllegalArgumentException: Geçersiz UUID dizesi: x

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.