Bagaimana cara menguji UUID / GUID yang valid?


270

Bagaimana cara memeriksa apakah variabel berisi pengidentifikasi UUID / GUID yang valid?

Saat ini saya hanya tertarik untuk memvalidasi tipe 1 dan 4, tetapi seharusnya tidak menjadi batasan untuk jawaban Anda.


dalam format string, bukan hex, bukan bin, atau saya tidak tahu apa yang Anda minta
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

Jika Anda tidak dapat mengecualikan variabel yang berisi rantai 32 digit hex berturut-turut (tanpa pengelompokan), lihat jawaban saya
Wolf

Jawaban:


413

Saat ini, UUID adalah sebagaimana ditentukan dalam RFC4122. Kasus tepi yang sering diabaikan adalah UUID NIL, yang disebutkan di sini . Regex berikut mempertimbangkan ini dan akan mengembalikan kecocokan untuk UUID NIL. Lihat di bawah ini untuk UUID yang hanya menerima UUID non-NIL. Kedua solusi ini adalah untuk versi 1 hingga 5 (lihat karakter pertama dari blok ketiga).

Karena itu untuk memvalidasi 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

... memastikan Anda memiliki UUID yang diformat kanonik yaitu Versi 1 hingga 5 dan merupakan Varian yang sesuai sesuai RFC4122.

CATATAN: Kawat gigi {dan }bukan kanonik. Mereka adalah artefak dari beberapa sistem dan penggunaan.

Mudah untuk memodifikasi regex di atas untuk memenuhi persyaratan pertanyaan aslinya.

PETUNJUK: regex grup / tangkapan

Untuk menghindari pencocokan 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
Saya pikir [1-5] [0-9a-f] {3} salah. Saya memiliki UUID yang valid yang memiliki "b06a" di bagian itu, dan ini gagal bagi saya.
Felipe Brahm

1
@FelipeBrahm, [1-5] benar menurut RFC, bahwa 4 bit menunjukkan versi, dan hanya ada 5 versi.
rvignacio

749d0000-0194-1005-2e05-08d61613bf2f gagal untuk saya dalam biola
merampas

1
Karena penasaran, (mengapa) tidak akan hal berikut ini berlaku juga: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}
tjeerdnet

58

regex untuk menyelamatkan

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

atau dengan kurung

/^\{?[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
atau jika Anda mungkin memiliki tanda kurung: / ^ \ {? [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');
ryanb

Ini tidak sepenuhnya benar. ia melewatkan bahwa [1-5] (versi) memulai blok ke-3 dan [89AB] (varian) memulai blok ke-4. Jawaban Gambol benar.
Wolf

7
Versi yang lebih ringkas (mengabaikan kurung):/^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/i
c24w

41

Jika Anda ingin memeriksa atau memvalidasi versi UUID tertentu, berikut adalah regex yang sesuai.

Perhatikan bahwa satu-satunya perbedaan adalah nomor versi , yang dijelaskan dalam 4.1.3. Versionbab UUID 4122 RFC .

Nomor versi adalah karakter pertama dari grup ketiga [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

Jika Anda menggunakan Node.js untuk pengembangan, disarankan untuk menggunakan paket yang disebut Validator. Ini mencakup semua regex yang diperlukan untuk memvalidasi versi berbeda dari UUID plus Anda mendapatkan berbagai fungsi lainnya untuk validasi.

Inilah tautan npm: Validator

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

Menarik, tetapi sepertinya ia mengharapkan tanda hubung? Berikut adalah empat regex yang saat ini digunakan - /^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i dan / atau /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i dan / atau /^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i dan / atau /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i
ruffin

1
Validator hanya mendukung UUID v3-5 bukan v1
peteb

13

Selain jawaban Gambol yang akan melakukan pekerjaan dalam hampir semua kasus , semua jawaban yang diberikan sejauh ini terlewatkan sehingga pemformatan yang dikelompokkan (8-4-4-4-12) tidak wajib untuk menyandikan GUID dalam teks . Ini digunakan sangat sering tetapi jelas juga rantai polos 32 digit heksadesimal dapat valid. [1] peningkatan regex :

/^[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] Pertanyaannya adalah tentang cek ing variabel s, jadi kami harus mencakup bentuk tidak ramah-pengguna juga.


Yang ini adalah fave saya. Bahkan lebih baik{?[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

Semua regex spesifik tipe yang diposting sejauh ini gagal pada UUID "tipe 0", didefinisikan dalam 4.1.7 dari RFC sebagai:

NIL UUID adalah bentuk khusus UUID yang ditentukan untuk mengatur semua 128 bit menjadi nol: 00000000-0000-0000-0000-000000000000

Untuk memodifikasi jawaban Wolf:

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

Atau, untuk mengecualikan "tipe 0" dengan benar tanpa semua nol, kami memiliki yang berikut (terima kasih kepada Luke):

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

Segmen UUID pertama dari nihil UUID harus memiliki 8 nol, bukan 7. Regex yang disediakan tidak memvalidasinya dengan 7.
Rich Seviora

2
Anda terlihat lebih baik tetapi memungkinkan beberapa UUID yang tidak valid, misalnya: abcdef00-0000-0000-0000-000000000000 akan cocok dengan regex Anda. Regex ini akan cocok dengan UUID yang valid, termasuk nol:/^(?:[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

terima kasih kepada @usertatha dengan beberapa modifikasi

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

Saya pikir jawaban Gambol hampir sempurna, tetapi salah mengartikan RFC 4122 § 4.1.1. Bagian varian sedikit.

Ini mencakup Varian-1 UUIDs (10xx = 8..b), tetapi tidak mencakup Varian-0 (0xxx = 0..7) dan varian Varian-2 (110x = c..d) yang dicadangkan untuk kompatibilitas ke belakang, jadi itu adalah UUID yang secara teknis valid. Varian-4 (111x = e..f) memang disediakan untuk penggunaan di masa mendatang, sehingga saat ini tidak valid.

Juga, 0 type tidak valid, "digit" itu hanya boleh 0 jika itu NIL UUID (seperti disebutkan dalam jawaban Evan ).

Jadi saya pikir regex paling akurat yang sesuai dengan spesifikasi RFC 4122 saat ini adalah (termasuk tanda hubung):

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

Gunakan metode .match () untuk memeriksa apakah String adalah 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 bukan fungsi
Deep Kakkar

1
Skrip yang diberikan bukan Javascript, yang diminta OP.
StefanJanssen

Jawaban yang disesuaikan dengan alamat komentar di atas. Solusi sekarang berfungsi seperti yang diharapkan.
DeeZone

Itu masih bukan js.
ktilcu

1

Versi yang sedikit dimodifikasi dari jawaban di atas ditulis dengan cara yang lebih ringkas. Ini akan memvalidasi GUID apa pun dengan tanda hubung (namun mudah dimodifikasi untuk menjadikan tanda hubung opsional). Ini juga akan mendukung karakter huruf besar dan kecil yang telah menjadi konvensi terlepas dari spesifikasinya:

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

Kuncinya di sini adalah bagian berulang di bawah ini

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

Yang hanya mengulangi pola 4 char 3 kali


1
A-fharus A-Fseperti itu:/^([0-9a-fA-F]{8})-(([0-9a-fA-F]{4}\-){3})([0-9a-fA-F]{12})$/i
DeeZone

jika Anda membawa case (/ i), mengapa mengulang af dan AF?
Nimrod

0

Cara yang baik untuk melakukannya di Node adalah dengan menggunakan ajvpaket ( 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

Saya pikir cara yang lebih baik adalah menggunakan metode statis dari Strtring untuk menghindari ekspresi reguler itu.

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

Di samping itu

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

throws java.lang.IllegalArgumentException: String UUID tidak valid: x

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.