Làm cách nào để kiểm tra xem biến có chứa định danh UUID / GUID hợp lệ không?
Tôi hiện chỉ quan tâm đến việc xác thực loại 1 và 4, nhưng nó không phải là giới hạn cho câu trả lời của bạn.
Làm cách nào để kiểm tra xem biến có chứa định danh UUID / GUID hợp lệ không?
Tôi hiện chỉ quan tâm đến việc xác thực loại 1 và 4, nhưng nó không phải là giới hạn cho câu trả lời của bạn.
Câu trả lời:
Hiện tại, UUID được quy định trong RFC4122. Một trường hợp cạnh thường bị bỏ qua là NIL UUID, được ghi chú ở đây . Regex sau đây tính đến điều này và sẽ trả về một trận đấu cho NIL UUID. Xem bên dưới để biết UUID chỉ chấp nhận UUID không NIL. Cả hai giải pháp này đều dành cho phiên bản 1 đến 5 (xem ký tự đầu tiên của khối thứ ba).
Do đó, để xác thực 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
... Đảm bảo bạn có UUID được định dạng chính tắc từ Phiên bản 1 đến 5 và là Biến thể phù hợp theo RFC4122.
LƯU Ý: Niềng răng {
và }
không hợp quy. Chúng là một tạo tác của một số hệ thống và tập quán.
Dễ dàng sửa đổi regex trên để đáp ứng các yêu cầu của câu hỏi ban đầu.
GỢI Ý: nhóm regex / chụp
Để tránh kết hợp 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 để giải cứu
/^[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');
hoặc có dấu ngoặc
/^\{?[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
Nếu bạn muốn kiểm tra hoặc xác nhận một phiên bản UUID cụ thể, đây là các biểu thức chính tương ứng.
Lưu ý rằng sự khác biệt duy nhất là số phiên bản , được giải thích trong
4.1.3. Version
chương của UUID 4122 RFC .
Số phiên bản là ký tự đầu tiên của nhóm thứ ba [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
Nếu bạn đang sử dụng Node.js để phát triển, bạn nên sử dụng gói có tên là Trình xác thực. Nó bao gồm tất cả các biểu thức cần thiết để xác thực các phiên bản khác nhau của UUID cộng với bạn có các chức năng khác để xác thực.
Đây là liên kết npm: Trình xác thực
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
và / hoặc /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i
và / hoặc /^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i
/ hoặc /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i
Bên cạnh câu trả lời của Gambol sẽ thực hiện công việc trong gần như tất cả các trường hợp , tất cả các câu trả lời cho đến nay đã bỏ lỡ rằng định dạng được nhóm (8-4-4-4-12) không bắt buộc phải mã hóa GUID trong văn bản . Nó được sử dụng rất thường xuyên nhưng rõ ràng cũng có một chuỗi đơn giản gồm 32 chữ số thập lục phân có thể hợp lệ. [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] Câu hỏi đặt ra là về kiểm tra ing biến s, vì vậy chúng ta nên bao gồm các hình thức sử dụng không thân thiện là tốt.
{?[0-9a-f]{8}-?[0-9a-f]{4}-?[1-5][0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}}?
Tất cả các biểu thức cụ thể theo loại được đăng cho đến nay đều không thành công trên "loại 0" Nil UUID, được định nghĩa trong 4.1.7 của RFC là:
UUID nil là dạng UUID đặc biệt được chỉ định để có tất cả 128 bit được đặt thành 0:
00000000-0000-0000-0000-000000000000
Để sửa đổi câu trả lời của 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
Hoặc, để loại trừ đúng "loại 0" mà không có tất cả các số không, chúng tôi có các mục sau (nhờ 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
abcdef00-0000-0000-0000-000000000000
sẽ khớp với biểu thức chính quy của bạn. Regex này sẽ khớp với các UUID hợp lệ, bao gồm cả số không:/^(?:[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
Tôi nghĩ rằng câu trả lời của Gambol gần như hoàn hảo, nhưng nó giải thích sai về RFC 4122 § 4.1.1. Phần biến thể một chút.
Nó bao gồm các biến thể Variant-1 UUID (10xx = 8..b), nhưng không bao gồm các biến thể Variant-0 (0xxx = 0..7) và Variant-2 (110x = c..d) được dành riêng cho khả năng tương thích ngược, vì vậy chúng là UUID hợp lệ về mặt kỹ thuật. Biến thể-4 (111x = e..f) thực sự được dành riêng cho sử dụng trong tương lai, vì vậy chúng hiện không hợp lệ.
Ngoài ra, loại 0 không hợp lệ, "chữ số" đó chỉ được phép là 0 nếu đó là NIL UUID (như được đề cập trong câu trả lời của Evan ).
Vì vậy, tôi nghĩ rằng regex chính xác nhất tuân thủ thông số RFC 4122 hiện tại là (bao gồm cả dấu gạch nối):
/^([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)
Sử dụng phương thức .match () để kiểm tra xem String có phải là UUID hay không.
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}$");
}
Một phiên bản sửa đổi một chút của các câu trả lời ở trên được viết theo cách ngắn gọn hơn. Điều này sẽ xác nhận bất kỳ GUID nào bằng dấu gạch nối (tuy nhiên dễ dàng sửa đổi để tạo dấu gạch nối tùy chọn). Điều này cũng sẽ hỗ trợ các ký tự chữ hoa và chữ thường đã trở thành quy ước bất kể đặc điểm kỹ thuật:
/^([0-9a-fA-F]{8})-(([0-9a-fA-F]{4}\-){3})([0-9a-fA-F]{12})$/i
Chìa khóa ở đây là phần lặp lại bên dưới
(([0-9a-fA-F]{4}\-){3})
Mà chỉ đơn giản là lặp lại 4 mẫu char 3 lần
A-f
nên A-F
như vậy:/^([0-9a-fA-F]{8})-(([0-9a-fA-F]{4}\-){3})([0-9a-fA-F]{12})$/i
Một cách tốt để làm điều đó trong Node là sử dụng ajv
gói ( 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
Tôi nghĩ rằng một cách tốt hơn là sử dụng phương thức tĩnh từString để tránh các biểu thức chính quy đó.
id = UUID.randomUUID();
UUID uuid = UUID.fromString(id.toString());
Assert.assertEquals(id.toString(), uuid.toString());
Mặt khác
UUID uuidFalse = UUID.fromString("x");
ném java.lang.IllegalArgumentException: Chuỗi UUID không hợp lệ: x