Regex के साथ पाठ में UUIDs की खोज करना


224

मैं एक regex का उपयोग करके पाठ के ब्लॉकों में UUIDs खोज रहा हूं। वर्तमान में मैं इस धारणा पर भरोसा कर रहा हूं कि सभी UUIDs 8-4-4-4-12 हेक्साडेसिमल पैट्स का पालन करेंगे।

क्या कोई ऐसे उपयोग के मामले के बारे में सोच सकता है जहां यह धारणा अमान्य होगी और इससे मुझे कुछ यूयूआईडी याद आएंगे?


6 साल पहले का यह प्रश्न मुझे टेक्स्ट के ब्लॉक में क्रेडिट कार्ड खोजने के लिए एक प्रोजेक्ट में मदद करने के लिए था। मैंने बाद में अपने ब्लॉग पोस्ट से लिंक किए गए कोड को ओपन कर दिया है, जो इस बात की व्याख्या करता है कि UUIDs क्रेडिट कार्ड के लिए खोज करते समय उत्पन्न हो रहे थे manellisrocks.com/2013/11/…
लड़के

4
UUID नियमित अभिव्यक्ति पैटर्न मिलान के लिए एक खोज ने मुझे इस स्टैक ओवरफ्लो पोस्ट पर लाया लेकिन स्वीकृत उत्तर वास्तव में एक उत्तर नहीं है। इसके अतिरिक्त, आपके प्रश्न के नीचे दिए गए लिंक में भी पैटर्न नहीं है (जब तक कि मैं कुछ याद नहीं कर रहा हूं)। इन जवाबों में से एक है जिसे आपने उपयोग करके समाप्त किया है?
Tass

यदि आप मेरे द्वारा पोस्ट किए गए लिंक के खरगोश वॉरन का अनुसरण करते हैं, तो मैंने आपको GitHub में इस लाइन के पार आ सकता है, जिसमें रेगेक्स है जो मैंने अंततः उपयोग किया था। (यह समझना मुश्किल है कि इसे ढूंढना मुश्किल है।) वह कोड और वह फ़ाइल आपकी मदद कर सकती है: github.com/guyellis/CreditCard/blob/master/Company.CreditCard/…
Guy

1
इन सभी में से कोई भी उत्तर केवल मान्य RFC 4122 UUID के सभी वेरिएंट के लिए एकल रेगेक्स नहीं लगता है। लेकिन ऐसा लगता है कि इस तरह का जवाब यहां दिया गया था: stackoverflow.com/a/13653180/421049
गैरेट विल्सन

जवाबों:


41

मैं मानता हूं कि परिभाषा से आपका रेगेक्स किसी भी यूयूआईडी को याद नहीं करता है। हालाँकि यह नोट करना उपयोगी हो सकता है कि यदि आप विशेष रूप से Microsoft के वैश्विक स्तर पर विशिष्ट पहचानकर्ताओं (GUID) के लिए खोज कर रहे हैं, तो GUID के लिए पाँच समान स्ट्रिंग प्रतिनिधित्व हैं:

"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}}" 

3
पहला पैटर्न किन स्थितियों में मिलेगा? यानी एक .Net फ़ंक्शन है जो हाइफ़न को छीन लेगा या हाइफ़न के बिना GUID लौटाएगा?
गाय

1
आप इसे myGuid.ToString ("N") से प्राप्त कर सकते हैं।
पैनासोस

462

Uid के लिए रेगीक्स है:

\b[0-9a-f]{8}\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\b[0-9a-f]{12}\b

19
वह बनाओ [a-f0-9]! जैसा कि यह हेक्स है! आपका regex (जैसा कि है) झूठी सकारात्मक लौटा सकता है।
exhuma

13
कुछ मामलों में आप यह भी बनाना चाह सकते हैं कि [a-fA-F0-9] या [A-F0-9]।
हंस-पीटर स्टॉर 12

22
@ साइबर-भिक्षु: [0-9a-f] अर्थ और गति में [a-f0-9] और [0123456789abcdef] के समान है, क्योंकि रेगेक्स को वैसे भी राज्य मशीन में बदल दिया जाता है, प्रत्येक हेक्स अंक के साथ बदल जाता है राज्य-तालिका में प्रविष्टि। यह कैसे काम करता है, इस पर एक प्रविष्टि बिंदु के लिए, en.wikipedia.org/wiki/Nondeterministic_finite_automaton
जेसपरम्स

10
यह समाधान काफी सही नहीं है। यह उन ID से मेल खाता है जिनके पास RFC4122 प्रति अमान्य संस्करण और भिन्न वर्ण हैं। @ गजस का समाधान उस संबंध में अधिक सही है। इसके अलावा, RFC इनपुट पर ऊपरी-केस वर्णों की अनुमति देता है, इसलिए [AF] जोड़ना उचित होगा।
ब्रूफो

4
@broofa, मैं देखता हूं कि आप वास्तव में केवल UUIDs से मेल खाने वाले सभी लोगों पर सेट हैं जो RFC के अनुरूप हैं। हालांकि, मुझे लगता है कि इस तथ्य को आपने कई बार इंगित किया है कि यह एक ठोस संकेतक है जो सभी UUIDs RFC संस्करण और संस्करण संकेतक का उपयोग नहीं करेंगे। UUID परिभाषा en.wikipedia.org/wiki/Uuid#Definition में 8-4-4-4-12 सरल और 2 ^ 128 संभावनाएँ हैं। RFC केवल एक सबसेट का प्रतिनिधित्व करता है। तो आप क्या मिलान करना चाहते हैं? सबसेट, या उन सभी को?
ब्रूनो ब्रोंस्की

120

@ivelin: UUID में राजधानियाँ हो सकती हैं। तो आपको या तो स्ट्रिंग (या स्ट्रिंग) का उपयोग करने की आवश्यकता होगी:

[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}

अभी इस टिप्पणी की है, लेकिन पर्याप्त प्रतिनिधि नहीं होगा :)


22
आमतौर पर आप पैटर्न को आई के साथ असंवेदनशील के रूप में मामले को परिभाषित करके इसे संभाल सकते हैं, यह एक क्लीनर पैटर्न बनाता है: / [0-9a-f] {8} - [0-9a-f] {4} - [0 -9a-f] {4} - [0-9a-f] {4} - [0-9a-f] {12} / i
थॉमस बिंडज़स

@ThomasBindzus वह विकल्प सभी भाषाओं में उपलब्ध नहीं है। इस उत्तर में मूल पैटर्न ने मेरे लिए गो में काम किया। /.../iसंस्करण नहीं किया।
क्रिस रेडफोर्ड

110

संस्करण 4 यूयूआईडी में फॉर्म xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx होता है, जहां x कोई भी हेक्साडेसिमल अंक होता है और y 8, 9, A, या B. में से एक होता है। उदाहरण के लिए G47ac10b-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}/

मुझे नहीं लगता कि आपका मतलब अज़ है।
ब्रूनो ब्रोंस्की 16

8
[एएफ] को भी स्वीकार करने की आवश्यकता है। RFC4122 की धारा 3 के अनुसार: 'हेक्साडेसिमल मान "ए" के माध्यम से "एफ" लोअर केस कैरेक्टर के रूप में आउटपुट हैं और इनपुट पर असंवेदनशील हैं ।' इसके अलावा (:?8|9|A|B)शायद थोड़ा अधिक पठनीय है[89aAbB]
ब्रोफ

1
@ ब्रूफ की संशोधन को कॉपी करने की आवश्यकता है; जैसा कि आपका निम्न-मामला A या B. शामिल करता है
ELLIOTTCABLE

6
@elliottcable आपके वातावरण पर निर्भर करता है, बस i(केस- इनसेन्सिटिव ) ध्वज का उपयोग करें।
गजस

20
आप संस्करण 1 से 3 को अस्वीकार कर रहे हैं और 5. क्यों?
आईजीएल

90

यदि आप किसी विशिष्ट UUID संस्करण को जांचना या मान्य करना चाहते हैं, तो यहां संबंधित रेग्जेस हैं।

ध्यान दें कि एकमात्र अंतर संस्करण संख्या है , जिसे यूयूआईडी 4122 आरएफसी के4.1.3. Version अध्याय में समझाया गया है ।

संस्करण संख्या तीसरे समूह का पहला वर्ण है [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दायरे के बगल में होना चाहिए ।
Paweł Psztyć

27
iकेस संवेदी के रूप में regex के निशान यह के अंत में।
जोहानले 30१

एक पैटर्न संशोधक हमेशा इस्तेमाल नहीं किया जा सकता है। उदाहरण के लिए, एक ओपापी परिभाषा में, पैटर्न संवेदनशील है
स्टीफन जेनिकॉड

1
@StephaneJanicaud OpenAPI में, आपको formatUUIDs का परीक्षण करने के लिए regex का उपयोग करने के बजाय इसे "uuid" पर सेट करके संशोधक का उपयोग करना चाहिए : swagger.io/docs/specification//ata-models/data-types/#format
Ivan Gabriele

टिप के लिए @IvanGabriele धन्यवाद, यह सिर्फ एक उदाहरण था, यह एक ही समस्या है जब आप किसी भी मामले को असंवेदनशील पैटर्न की जांच नहीं करते।
स्टीफन जेनिकुड

35
/^[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 का regexp UUID V1-3 और 5 को अस्वीकार करता है, भले ही वे मान्य हों।


1
लेकिन यह अमान्य संस्करणों (जैसे 8 या ए) और अमान्य वेरिएंट की अनुमति देता है।
ब्राइस

ध्यान दें कि AB [89AB] [0-9a-f] में ऊपरी मामला है और बाकी के स्वीकृत अक्षर निचले मामले हैं। इसने मुझे पाइथन
टोनी सीपिया

17

[\w]{8}(-[\w]{4}){3}-[\w]{12} ज्यादातर मामलों में मेरे लिए काम किया है।

या यदि आप वास्तव में विशिष्ट होना चाहते हैं [\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12}


3
यह ध्यान देने योग्य बात है कि जावा में, कम से कम, साथ ही हेक्साडेसिमल अंकों से भी मेल खाता है। \ W की जगह \ p {XDigit} अधिक उपयुक्त हो सकता है क्योंकि हेक्साडेसिमल अंकों के मिलान के लिए POSIX वर्ग को परिभाषित किया गया है। अन्य यूनिकोड वर्णसेट थियो का उपयोग करते समय यह टूट सकता है।
ओशनोरो ०

1
@ नारियल का \wअर्थ आमतौर पर "शब्द वर्ण" होता है यह हेक्स-अंकों से बहुत अधिक मेल खाएगा। आपका समाधान काफी बेहतर है। या, अनुकूलता / पठनीयता के लिए आप इस्तेमाल कर सकते हैं[a-f0-9]
exhuma

1
यहाँ एक स्ट्रिंग है जो एक रेगेक्स की तरह दिखता है और उन पैटर्नों से मेल खाता है, लेकिन एक अमान्य रेगेक्स है: 2wtu37k5-q174-4418-2cu2-276e4j82sv19
ट्रैविस स्टीवन

@OleTraveler सच नहीं है, एक आकर्षण की तरह काम करता है। 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')
टॉमस वोजिक

3
@tom वह स्ट्रिंग (2wt ...) एक अमान्य UUID है, लेकिन इस उत्तर में दिया गया पैटर्न मेल खाता है जो स्ट्रिंग को गलत संकेत देता है कि यह एक वैध UUID है। यह बहुत बुरा है मुझे याद नहीं है कि क्यों UUID अमान्य है।
ट्रैविस स्टीवंस

10

पायथन री में, आप संख्या से ऊपरी मामले अल्फा तक फैला सकते हैं। इसलिए..

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']

यह सबसे सरल अजगर UUID regex बनाता है:

re_uuid = re.compile("[0-F]{8}-([0-F]{4}-){3}[0-F]{12}", re.I)

मैं इसे प्रदर्शन के लिए तुलना करने के लिए समय का उपयोग करने के लिए एक अभ्यास के रूप में छोड़ दूँगा।

का आनंद लें। इसे पाइथोनिक ™ रखें!

नोट: वे स्पैन भी मेल खाएंगे :;<=>?@', यदि आपको संदेह है कि आप झूठी सकारात्मकता दे सकते हैं, तो शॉर्टकट न लें। (टिप्पणियों में यह बताने के लिए ऑलिवर ऑबर्ट का धन्यवाद।)


2
[०-एफ] वास्तव में ०- ९ और एएफ से मेल खाएगा, लेकिन साथ ही ऐसा कोई भी चरित्र जिसका एएससीआईआई कोड ५ ((९) और ६५ (ए के लिए) के बीच है, जो कि किसी के भी कहने का है: <=>! @ ’।
ओलिवियर ऑबर्ट

7
इसलिए यदि आप विचार करना चाहते हैं, तो उपरोक्त कोड का उपयोग न करें: =>?;?: - <@ = - - @ = ​​- = - @ - @: -> == ==> =? = @? एक वैध यूयूआईडी :-) के रूप में
ओलिवियर ऑबर्ट

9

परिभाषा के अनुसार, एक यूयूआईडी 32 हेक्साडेसिमल अंक है, जिसे हाइफ़न द्वारा 5 समूहों में अलग किया गया है, जैसा आपने वर्णित किया है। आपको अपनी नियमित अभिव्यक्ति के साथ कोई कमी नहीं करनी चाहिए।

http://en.wikipedia.org/wiki/Uuid#Definition


2
गलत। RFC4122 केवल संस्करण अंक के लिए [1-5], और [89aAbB] संस्करण अंक के लिए अनुमति देता है।
ब्रूफ़

6

इसलिए, मुझे लगता है कि रिचर्ड ब्रोंस्की के पास वास्तव में आज तक का सबसे अच्छा जवाब है, लेकिन मुझे लगता है कि आप इसे कुछ हद तक सरल बनाने के लिए कर सकते हैं (या कम से कम निडर):

re_uuid = re.compile(r'[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}', re.I)

1
यहां तक ​​कि निडर:re_uuid = re.compile(r'[0-9a-f]{8}(?:-[0-9a-f]{4}){4}[0-9a-f]{8}', re.I)
पेड्रो गिमेनो

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];

5

UUID के लिए OS X पर जेनरेट किया गया uuidgen, रेगेक्स पैटर्न है

[A-F0-9]{8}-[A-F0-9]{4}-4[A-F0-9]{3}-[89AB][A-F0-9]{3}-[A-F0-9]{12}

के साथ सत्यापित करें

uuidgen | grep -E "[A-F0-9]{8}-[A-F0-9]{4}-4[A-F0-9]{3}-[89AB][A-F0-9]{3}-[A-F0-9]{12}"

2
$UUID_RE = join '-', map { "[0-9a-f]{$_}" } 8, 4, 4, 4, 12;

BTW, केवल 4 पदों में से एक पर अनुमति देता है केवल UUIDv4 के लिए मान्य है। लेकिन v4 केवल UUID संस्करण नहीं है जो मौजूद है। मैंने अपने अभ्यास में v1 भी पूरा किया है।


1

यदि Posix regex ( grep -E, MySQL, आदि) का उपयोग कर रहे हैं , तो यह पढ़ना और याद रखना आसान हो सकता है:

[[:xdigit:]]{8}(-[[:xdigit:]]{4}){3}-[[:xdigit:]]{12}

0

बैश के लिए:

grep -E "[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}"

उदाहरण के लिए:

$> echo "f2575e6a-9bce-49e7-ae7c-bff6b555bda4" | grep -E "[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}"
f2575e6a-9bce-49e7-ae7c-bff6b555bda4
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.