정규식을 사용하여 텍스트 블록에서 UUID를 검색하고 있습니다. 현재 모든 UUID가 8-4-4-4-12 16 진수 패턴을 따르는 것으로 가정하고 있습니다.
누구 든지이 가정이 유효하지 않아 UUID를 놓칠 수있는 유스 케이스를 생각할 수 있습니까?
정규식을 사용하여 텍스트 블록에서 UUID를 검색하고 있습니다. 현재 모든 UUID가 8-4-4-4-12 16 진수 패턴을 따르는 것으로 가정하고 있습니다.
누구 든지이 가정이 유효하지 않아 UUID를 놓칠 수있는 유스 케이스를 생각할 수 있습니까?
답변:
나는 당신의 정규 표현식이 UUID를 놓치지 않는다는 것에 동의합니다. 그러나 특히 Microsoft의 GUID (Globally Unique Identifier)를 검색하는 경우 GUID에 대해 5 개의 동등한 문자열 표현이 있습니다.
"ca761232ed4211cebacd00aa0057b223"
"CA761232-ED42-11CE-BACD-00AA0057B223"
"{CA761232-ED42-11CE-BACD-00AA0057B223}"
"(CA761232-ED42-11CE-BACD-00AA0057B223)"
"{0xCA761232, 0xED42, 0x11CE, {0xBA, 0xCD, 0x00, 0xAA, 0x00, 0x57, 0xB2, 0x23}}"
UUID의 정규식은 다음과 같습니다.
\b[0-9a-f]{8}\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\b[0-9a-f]{12}\b
[a-f0-9]
! 16 진수로! 정규식은 (있는 그대로) 오 탐지를 반환 할 수 있습니다.
@ivelin : UUID는 수도를 가질 수 있습니다. 따라서 문자열을 toLowerCase ()하거나 다음을 사용해야합니다.
[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}
방금 이것을 언급했지만 충분하지 않은 담당자 :)
/.../i
버전은하지 않았다.
버전 4 UUID의 형식은 xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx입니다. 여기서 x는 16 진수이며 y는 8, 9, A 또는 B 중 하나입니다. 예를 들어 f47ac10b-58cc-4372-a567-0e02b2c3d479.
출처 : http://en.wikipedia.org/wiki/Uuid#Definition
따라서 이것은 기술적으로 더 정확합니다.
/[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}/
(:?8|9|A|B)
과 같이 약간 더 읽기 [89aAbB]
i
(대소 문자 구분) 플래그 만 사용하십시오 .
특정 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
a-f
각 A-F
범위 옆에 포함되어야합니다 .
i
경우를 구분와 같은 정규식 마크를 말에.
format
정규식을 사용하여 UUID를 테스트하는 대신 "uuid"로 설정 하여 수정자를 사용해야합니다 . swagger.io/docs/specification/data-models/data-types/#format
/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89AB][0-9a-f]{3}-[0-9a-f]{12}$/i
Gajus의 정규 표현식은 UUID V1-3 및 5가 유효하더라도 거부합니다.
[\w]{8}(-[\w]{4}){3}-[\w]{12}
대부분의 경우 나를 위해 일했습니다.
또는 당신이 정말로 구체적이기를 원한다면 [\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12}
.
\w
일반적으로 "단어 문자"를 의미합니다. 16 진수보다 훨씬 더 많이 일치합니다. 귀하의 솔루션이 훨씬 좋습니다. 또는 호환성 / 가독성을 위해 사용할 수 있습니다[a-f0-9]
import re def valid_uuid(uuid): regex = re.compile('[\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12}', re.I) match = regex.match(uuid) return bool(match) valid_uuid('2wtu37k5-q174-4418-2cu2-276e4j82sv19')
python re에서는 숫자에서 대문자로 확장 할 수 있습니다. 그래서..
import re
test = "01234ABCDEFGHIJKabcdefghijk01234abcdefghijkABCDEFGHIJK"
re.compile(r'[0-f]+').findall(test) # Bad: matches all uppercase alpha chars
## ['01234ABCDEFGHIJKabcdef', '01234abcdef', 'ABCDEFGHIJK']
re.compile(r'[0-F]+').findall(test) # Partial: does not match lowercase hex chars
## ['01234ABCDEF', '01234', 'ABCDEF']
re.compile(r'[0-F]+', re.I).findall(test) # Good
## ['01234ABCDEF', 'abcdef', '01234abcdef', 'ABCDEF']
re.compile(r'[0-f]+', re.I).findall(test) # Good
## ['01234ABCDEF', 'abcdef', '01234abcdef', 'ABCDEF']
re.compile(r'[0-Fa-f]+').findall(test) # Good (with uppercase-only magic)
## ['01234ABCDEF', 'abcdef', '01234abcdef', 'ABCDEF']
re.compile(r'[0-9a-fA-F]+').findall(test) # Good (with no magic)
## ['01234ABCDEF', 'abcdef', '01234abcdef', 'ABCDEF']
가장 간단한 Python UUID 정규식을 만듭니다.
re_uuid = re.compile("[0-F]{8}-([0-F]{4}-){3}[0-F]{12}", re.I)
나는 이것의 성능을 비교하기 위해 timeit을 사용하기 위해 독자에게 연습으로 남겨 두겠습니다.
즐겨. Pythonic ™ 유지하십시오!
참고 :이 범위도 일치 :;<=>?@'
하므로 오 탐지 가능성이 있다고 생각되면 바로 가기를 사용하지 마십시오. (댓글에서 지적 해 주신 Oliver Aubert에게 감사합니다.)
정의에 따르면 UUID는 설명 된 것처럼 16 개의 16 진수 32 개이며 하이픈으로 5 개의 그룹으로 구분됩니다. 정규식을 놓치지 마십시오.
C ++의 변형 :
#include <regex> // Required include
...
// Source string
std::wstring srcStr = L"String with GIUD: {4d36e96e-e325-11ce-bfc1-08002be10318} any text";
// Regex and match
std::wsmatch match;
std::wregex rx(L"(\\{[A-F0-9]{8}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{12}\\})", std::regex_constants::icase);
// Search
std::regex_search(srcStr, match, rx);
// Result
std::wstring strGUID = match[1];