유효한 UUID / GUID를 테스트하는 방법?


270

변수에 유효한 UUID / GUID 식별자가 포함되어 있는지 확인하는 방법은 무엇입니까?

현재 유형 1과 4의 유효성 검사에만 관심이 있지만 답변에 제한을 두어서는 안됩니다.


16 진수가 아닌 16 진수가 아닌 문자열 형식이거나, 무엇을 요청하는지 모르겠습니다.
— 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 개의 연속 16 진 숫자 체인을 포함하는 변수를 그룹화하지 않고 배제 할 수 없다면 내 대답을
— Wolf

답변:


413

현재 UUID는 RFC4122에 지정되어 있습니다. 종종 무시 가장자리 케이스는 언급 NIL UUID이며, 여기 . 다음 정규식에서는이를 고려하여 NIL UUID에 대한 일치 항목을 반환합니다. NIL이 아닌 UUID 만 허용하는 UUID는 아래를 참조하십시오. 이 솔루션은 모두 버전 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

... 버전 1에서 5까지의 정식 형식의 UUID가 있고 RFC4122에 따라 적절한 변형입니다.

참고 : 중괄호 {와 }정식 없습니다. 그것들은 일부 시스템과 사용법의 인공물입니다.

원래 질문의 요구 사항을 충족하기 위해 위의 정규식을 쉽게 수정할 수 있습니다.

힌트 : 정규식 그룹 / 캡처

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
[1-5] [0-9a-f] {3}이 (가) 잘못되었다고 생각합니다. 나는 그 부분에 "b06a"를 가진 유효한 UUID를 가지고 있는데, 이것은 나에게 실패했다.
— Felipe Brahm 2018 년

1
RFC에 따르면 @FelipeBrahm, [1-5]는 4 비트가 버전을 나타내며 5 가지 버전 만 있음을 의미합니다.
— rvignacio 2016 년

749d0000-0194-1005-2e05-08d61613bf2f 바이올린에서 나를 위해 실패
— 강탈

1
호기심에서 (왜) 다음도 유효하지 않을 것입니다 : [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}
— tjeerdnet

58

구조에 정규식

/^[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}‌​\}?$/

3
또는 대괄호가있는 경우 : / ^ \ {? [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

이것은 정확하지 않습니다. [1-5] (버전)가 3 번째 블록을 시작하고 [89AB] (변형)이 4 번째 블록을 시작하는 것을 놓칩니다. Gambol의 대답 이 옳습니다.
— Wolf

7
간결한 버전 (괄호 무시) :/^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/i
— c24w

41

특정 UUID 버전을 확인하거나 확인하려면 해당 정규식이 있습니다.

참고 것이 유일한 차이점은 버전 번호 에 설명되어, 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

39

개발에 Node.js를 사용하는 경우 Validator라는 패키지를 사용하는 것이 좋습니다. 여기에는 다른 버전의 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
— 러핀

1
검사기는 UUID가되지 V1 v3-5 지원
— peteb

13

거의 모든 경우에 작업 을 수행하는 Gambol의 답변 외에도 지금까지 주어진 모든 답변은 그룹화 된 형식 (8-4-4-4-12)이 GUID를 텍스트 로 인코딩하는 데 필수적이지는 않습니다 . 매우 자주 사용되지만 32 개의 16 진 숫자로 된 일반 체인도 유효합니다. [1] 정규식 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] 질문에 관한 검사 보내고 가변 우리는 물론 사용자가 비우호적 인 형태를 포함해야하므로들.


이것은 나의 fave입니다. 더 나은{?[0-9a-f]{8}-?[0-9a-f]{4}-?[1-5][0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}}?
— 마이크 넬슨

10

지금까지 게시 된 모든 유형별 정규 표현식은 RFC 4.1.7에 다음과 같이 정의 된 "유형 0"Nil UUID에서 실패합니다.

nil UUID는 128 비트를 모두 0으로 설정하도록 지정된 특수한 형태의 UUID입니다. 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"을 올바르게 제외하기 위해 다음과 같은 결과를 얻습니다 (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

nil UUID의 첫 UUID 세그먼트는 7이 아닌 8 개의 0을 가져야합니다. 제공된 정규 표현식은 7로 유효성을 검증하지 않았습니다.
— Rich Seviora

2
당신은 더 좋아 보이지만 일부 잘못된 UUID를 허용 abcdef00-0000-0000-0000-000000000000 합니다. 예 : 정규식과 일치합니다. 이 정규식은 다음을 포함한 유효한 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
— Luke

10

약간의 수정으로 @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;
}

2

나는 Gambol의 대답 이 거의 완벽 하다고 생각 하지만 RFC 4122 § 4.1.1을 잘못 해석합니다 . 변형 섹션 이 조금 있습니다.

Variant-1 UUID (10xx = 8..b)는 다루지 만 이전 버전과의 호환성을 위해 예약 된 Variant-0 (0xxx = 0..7) 및 Variant-2 (110x = c..d) 변형은 다루지 않습니다. 기술적으로 유효한 UUID입니다. 변형 -4 (111x = e..f)는 나중에 사용하기 위해 예약되어 있으므로 현재 유효하지 않습니다.

또한 0 유형이 유효하지 않습니다. "숫자"는 NIL UUID 인 경우에만 0이 될 수 있습니다 ( Evan 's answer 에서 언급 한 것처럼 ).

따라서 현재 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)

1

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

잡히지 않은 TypeError : s.matches는 함수가 아닙니다
— Deep Kakkar

1
지정된 스크립트는 Javascript가 아니며 OP가 요청한 것입니다.
— StefanJanssen

위의 의견을 해결하기 위해 조정 된 답변. 솔루션이 이제 예상대로 작동합니다.
— DeeZone

그것은 여전히 ​​js가 아닙니다.
— ktilcu

1

위의 답변 중 약간 수정 된 버전 이보다 간결하게 작성되었습니다. 하이픈이있는 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 번 반복합니다.


1
A-f해야한다 A-F:과 같이/^([0-9a-fA-F]{8})-(([0-9a-fA-F]{4}\-){3})([0-9a-fA-F]{12})$/i
— DeeZone

대 / 소문자를 구분하지 않는 경우 왜 af를 반복 한 다음 AF를 반복해야합니까?
— Nimrod

0

노드에서이를 수행하는 좋은 방법은 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

-1

더 좋은 방법은 정적 메서드 fromString을 사용하여 정규 표현식을 피하는 것입니다.

    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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.