จะตรวจสอบว่าตัวแปรมีตัวระบุ UUID / GUID ที่ถูกต้องได้อย่างไร
ขณะนี้ฉันสนใจเฉพาะการตรวจสอบประเภท 1 และ 4 แต่ไม่ควร จำกัด เฉพาะคำตอบของคุณ
จะตรวจสอบว่าตัวแปรมีตัวระบุ UUID / GUID ที่ถูกต้องได้อย่างไร
ขณะนี้ฉันสนใจเฉพาะการตรวจสอบประเภท 1 และ 4 แต่ไม่ควร จำกัด เฉพาะคำตอบของคุณ
คำตอบ:
ขณะนี้ UUID มีการระบุไว้ใน RFC4122 กรณีที่ขอบมักจะถูกละเลยเป็น NIL UUID ตั้งข้อสังเกตที่นี่ regex ต่อไปนี้พิจารณาสิ่งนี้และจะส่งคืนการแข่งขันสำหรับ NIL UUID ดูด้านล่างสำหรับ UUID ซึ่งยอมรับเฉพาะ UIL ที่ไม่ใช่ NIL เท่านั้น โซลูชันทั้งสองนี้ใช้สำหรับเวอร์ชัน 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
หมายเหตุ: การจัดฟัน{
และ}
ไม่ใช่แบบบัญญัติ มันเป็นสิ่งประดิษฐ์ของระบบและประเพณีบางอย่าง
ง่ายต่อการแก้ไข regex ข้างต้นเพื่อตอบสนองความต้องการของคำถามเดิม
คำแนะนำ: กลุ่ม / การบันทึก regex
วิธีหลีกเลี่ยงการจับคู่ 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 เพื่อช่วยเหลือ
/^[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 เฉพาะนี่คือ regexes ที่เกี่ยวข้อง
โปรดทราบว่าแตกต่างเพียงอย่างเดียวคือหมายเลขรุ่นซึ่งจะอธิบายใน
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 มันรวมถึง regexes ทั้งหมดที่จำเป็นในการตรวจสอบรุ่นที่แตกต่างกันของ UUID รวมทั้งคุณจะได้รับฟังก์ชั่นอื่น ๆ อีกมากมายสำหรับการตรวจสอบ
นี่คือลิงค์ 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
และ / หรือ /^[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
ข้างคำตอบ Gambol ของที่จะทำผลงานได้ในเกือบทุกกรณีคำตอบทั้งหมดที่อยู่พลาดเพื่อให้ห่างไกลว่าการจัดรูปแบบการจัดกลุ่ม (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]คำถามที่เป็นเรื่องเกี่ยวกับการตรวจสอบไอเอ็นจีตัวแปร s ดังนั้นเราควรจะรวมถึงรูปแบบการใช้งานที่ไม่เป็นมิตรเช่นกัน
{?[0-9a-f]{8}-?[0-9a-f]{4}-?[1-5][0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}}?
regexes เฉพาะประเภททั้งหมดที่โพสต์จนถึงขณะนี้ล้มเหลวใน "ชนิด 0" ไม่มี UUID ที่กำหนดใน 4.1.7 ของ RFC เป็น:
nil UUID เป็นรูปแบบพิเศษของ UUID ที่ระบุว่ามี 128 บิตทั้งหมดตั้งค่าเป็นศูนย์:
00000000-0000-0000-0000-000000000000
หากต้องการแก้ไขคำตอบของ 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
หรือหากต้องการยกเว้น "ประเภท 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
จะจับคู่ regex ของคุณ regex นี้จะตรงกับ 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
ขอบคุณ @usertatha ที่มีการดัดแปลงบางอย่าง
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;
}
ฉันคิดว่าคำตอบของ Gambolนั้นเกือบจะสมบูรณ์แบบ แต่มันตีความตีความRFC 4122 § 4.1.1 ผิด ส่วนตัวแปรเล็กน้อย
มันครอบคลุม Variant-1 UUIDs (10xx = 8..b) แต่ไม่ครอบคลุม Variant-0 (0xxx = 0..7) และ Variant-2 (110x = c..d) รุ่นที่สงวนไว้สำหรับความเข้ากันได้แบบย้อนหลัง ดังนั้นมันจึงเป็น UUID ที่ถูกต้องทางเทคนิค Variant-4 (111x = e..f) ถูกสงวนไว้สำหรับใช้ในอนาคตดังนั้นจึงไม่สามารถใช้งานได้ในปัจจุบัน
นอกจากนี้ประเภท 0 ไม่ถูกต้องว่า "หลัก" ได้รับอนุญาตให้เป็น 0 เท่านั้นหากเป็น NIL UUID (เช่นที่กล่าวถึงในคำตอบของ Evan )
ดังนั้นฉันคิดว่า regex ที่แม่นยำที่สุดที่สอดคล้องกับข้อกำหนด 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
ฉันคิดว่าวิธีที่ดีกว่าคือการใช้วิธีการคงที่จาก String เพื่อหลีกเลี่ยงการแสดงผลปกติเหล่านั้น
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