नियमित अभिव्यक्तियाँ क्या हैं?
नियमित अभिव्यक्तियाँ, जिन्हें रेगेक्स के नाम से भी जाना जाता है, पैटर्न को परिभाषित करके काम करती हैं जिनका उपयोग आप स्ट्रिंग्स के अंदर कुछ वर्णों या शब्दों को खोजने के लिए कर सकते हैं।
एक बार जब आप उस पैटर्न को परिभाषित कर लेते हैं जिसका आप उपयोग करना चाहते हैं, तो आप संपादन कर सकते हैं, कुछ वर्णों या शब्दों को हटा सकते हैं, एक चीज़ को दूसरी से बदल सकते हैं, किसी फ़ाइल या किसी भी स्ट्रिंग से प्रासंगिक जानकारी निकाल सकते हैं जिसमें वह विशेष पैटर्न होता है, और इसी तरह।
आपको रेगेक्स क्यों सीखना चाहिए?
रेगेक्स आपको टेक्स्ट प्रोसेसिंग करने का एक ऐसा तरीका देता है जो आपका बहुत समय बचा सकता है। यह प्रक्रिया में कुछ मज़ा भी जोड़ सकता है।
रेगेक्स का उपयोग करके जानकारी ढूंढना बहुत आसान हो जाता है। एक बार जब आप अपना लक्ष्य ढूंढ लेते हैं, तो आप बैच संपादन/प्रतिस्थापन/हटाना या जो भी प्रोसेसिंग आपको करने की आवश्यकता है, कर सकते हैं।
रेगेक्स के उपयोग के कुछ व्यावहारिक उदाहरण हैं बैच फ़ाइल नाम बदलना, लॉग पार्स करना, फॉर्म मान्य करना, कोडबेस में बड़े पैमाने पर संपादन करना, और रिकर्सिव खोज।
इस ट्यूटोरियल में, हम इस साइट की मदद से रेगेक्स की मूल बातें कवर करने जा रहे हैं। बाद में, मैं कुछ रेगेक्स चुनौतियों का परिचय दूंगा जिन्हें आप पायथन का उपयोग करके हल करेंगे। मैं आपको यह भी दिखाऊंगा कि sed और grep जैसे टूल का उपयोग रेगेक्स के साथ कैसे करें।
जीवन में कई चीजों की तरह, नियमित अभिव्यक्तियाँ उन चीजों में से एक हैं जिन्हें आप केवल करके वास्तव में समझ सकते हैं। मैं आपको इस लेख को पढ़ते समय रेगेक्स के साथ प्रयोग करने के लिए प्रोत्साहित करता हूँ।
विषय सूची
- रेगेक्स मूल बातें
- सटीक मिलान
- वर्ण सेट
- रेगेक्स में रेंज मिलान
- सेट में नहीं होने वाले किसी भी वर्ण का मिलान
- वर्ण वर्ग
- क्वांटिफायर
- कैप्चर समूह
- रेगेक्स में तार्किक OR का उपयोग कैसे करें
- कैप्चर समूहों को संदर्भित कैसे करें
- कैप्चर समूहों को नाम कैसे दें
- कमांड लाइन टूल के साथ रेगेक्स का उपयोग कैसे करें
- grep के साथ रिकर्सिव रेगेक्स खोज
- sed के साथ प्रतिस्थापन
- उन्नत रेगेक्स: लुकअराउंड
- लुकबिहाइंड
- लुकअहेड
- रेगेक्स के व्यावहारिक उदाहरण
- लॉग पार्सिंग
- बल्क फ़ाइल नाम बदलना
- ईमेल सत्यापन
- पासवर्ड बाधाएं
- अंतिम शब्द
रेगेक्स मूल बातें
एक नियमित अभिव्यक्ति पैटर्न से मेल खाने वाले वर्णों का एक क्रम मात्र है। लिटरल वर्णों (जैसे 'abc') का उपयोग करने के अलावा, कुछ मेटा वर्ण (*, +, ? आदि) हैं जिनके विशेष उद्देश्य हैं। वर्ण वर्ग जैसी विशेषताएं भी हैं जो आपके नियमित अभिव्यक्तियों को सरल बनाने में मदद कर सकती हैं।
कोई भी रेगेक्स लिखने से पहले, आपको उस पैटर्न के लिए सभी बुनियादी मामलों और एज केस के बारे में जानना होगा जिसे आप ढूंढ रहे हैं।
उदाहरण के लिए, यदि आप 'Hello World' से मिलान करना चाहते हैं, तो क्या आप चाहते हैं कि लाइन 'Hello' से शुरू हो या यह किसी भी चीज़ से शुरू हो सकती है? क्या आप 'Hello' और 'World' के बीच ठीक एक स्पेस चाहते हैं या अधिक हो सकते हैं? क्या 'World' के बाद अन्य वर्ण आ सकते हैं या लाइन वहीं समाप्त होनी चाहिए? क्या आप केस सेंसिटिविटी की परवाह करते हैं? और इसी तरह।
ये वे प्रश्न हैं जिनके उत्तर आपके पास होने चाहिए इससे पहले कि आप अपना रेगेक्स लिखने बैठें।
सटीक मिलान
रेगेक्स का सबसे बुनियादी रूप टेक्स्ट एडिटर में Ctrl-F की तरह ही वर्णों के अनुक्रम का मिलान करना है।
ऊपर आप मिलान की संख्या देख सकते हैं, और नीचे प्रत्येक वर्ण के लिए रेगेक्स क्या मिलान करता है इसकी व्याख्या प्रदान की गई है।
वर्ण सेट
रेगेक्स वर्ण सेट आपको वर्णों के समूह से किसी एक वर्ण का मिलान करने की अनुमति देते हैं। समूह को वर्गाकार कोष्ठक [] से घिरा होता है।
उदाहरण के लिए, t[ah]i "tai" और "thi" से मेल खाता है। यहां 't' और 'i' निश्चित हैं लेकिन उनके बीच 'a' या 'h' आ सकता है।
रेगेक्स में रेंज मिलान
कभी-कभी आप वर्णों के एक समूह का मिलान करना चाह सकते हैं जो प्रकृति में क्रमिक हैं, जैसे कोई भी अपरकेस अंग्रेजी अक्षर। लेकिन सभी 26 अक्षरों को लिखना काफी थकाऊ होगा।
रेगेक्स रेंज के साथ इस समस्या को हल करता है। "-" रेंज ऑपरेटर के रूप में कार्य करता है। नीचे कुछ वैध रेंज दिखाई गई हैं:
रेंजमिलान [A-Z]अपरकेस अक्षर [a-z]लोअरकेस अक्षर [0-9]कोई भी अंकआप आंशिक रेंज भी निर्दिष्ट कर सकते हैं, जैसे [b-e] 'bcde' अक्षरों में से किसी का मिलान करने के लिए या [3-6] '3456' संख्याओं में से किसी का मिलान करने के लिए।
आप एक वर्ण सेट के अंदर केवल एक रेंज निर्दिष्ट करने तक सीमित नहीं हैं। आप कई रेंज का उपयोग कर सकते हैं और उन्हें किसी अन्य अतिरिक्त वर्ण के साथ भी जोड़ सकते हैं। यहां, [3-6u-w;] '3456uvw' या सेमीकोलन ';' में से किसी का मिलान करेगा।
सेट में नहीं होने वाले किसी भी वर्ण का मिलान
यदि आप सेट को '^' से पूर्वनिर्धारित करते हैं, तो व्युत्क्रम ऑपरेशन किया जाएगा। उदाहरण के लिए, [^A-Z0-9] अपरकेस अक्षरों और अंकों को छोड़कर किसी भी चीज़ से मेल खाएगा।
वर्ण वर्ग
रेगेक्स लिखते समय, आपको अक्सर और एक ही अभिव्यक्ति में कई बार अंकों जैसे कुछ समूहों का मिलान करना होगा।
तो उदाहरण के लिए, आप 'अक्षर-अंक-अक्षर-अंक' जैसे पैटर्न का मिलान कैसे करेंगे?
अब तक आपने जो सीखा है, उसके साथ आप [a-zA-Z]-[0-9]-[a-zA-z]-[0-9] के साथ आ सकते हैं। यह काम करता है, लेकिन आप देख सकते हैं कि जैसे-जैसे पैटर्न की लंबाई बढ़ती है, अभिव्यक्ति काफी गन्दी हो सकती है।
अभिव्यक्ति को सरल बनाने के लिए, अंकों जैसे अच्छी तरह से परिभाषित वर्ण समूहों को वर्ग सौंपे गए हैं। निम्न तालिका इन वर्गों और उनके समकक्ष वर्ण सेट अभिव्यक्ति को दिखाती है:
वर्गमिलानसमकक्ष अभिव्यक्ति .न्यूलाइन को छोड़कर कुछ भी[^\n\r] \wवर्ड वर्ण[a-zA-Z0-9_] \Wनॉन-वर्ड वर्ण[^\w] \dअंक[0-9] \Dनॉन-अंक[^\d] \sस्पेस, टैब, न्यूलाइन[ \t\r\n\f] \Sनॉन-व्हाइटस्पेस वर्ण[^\s]वर्ण वर्ग काफी उपयोगी हैं और आपकी अभिव्यक्तियों को बहुत क्लीन बनाते हैं। हम इस ट्यूटोरियल में इनका बड़े पैमाने पर उपयोग करेंगे, इसलिए आप इस तालिका को एक संदर्भ बिंदु के रूप में उपयोग कर सकते हैं और यदि आप किसी वर्ग को भूल जाते हैं तो यहां वापस आ सकते हैं।
अधिकांश समय, हमें पैटर्न में सभी स्थितियों की परवाह नहीं होगी। "." वर्ग हमें एक सेट में सभी संभावित वर्ण लिखने से बचाता है।
उदाहरण के लिए, t.. किसी भी चीज़ से मेल खाता है जो t से शुरू होती है और उसके बाद कोई भी दो वर्ण होते हैं। यह आपको SQL LIKE ऑपरेटर की याद दिला सकता है जो वही काम करने के लिए t%% का उपयोग करेगा।
क्वांटिफायर
"पैटर्न" और "पुनरावृत्ति" शब्द साथ-साथ चलते हैं। यदि आप 3 अंकों की संख्या का मिलान करना चाहते हैं तो आप \d\d\d का उपयोग कर सकते हैं। लेकिन क्या होगा यदि आपको 11 अंकों का मिलान करना है? आप '\d' को 11 बार लिख सकते हैं, लेकिन रेगेक्स या किसी भी प्रकार की प्रोग्रामिंग करते समय एक सामान्य नियम यह है कि यदि आप खुद को किसी चीज़ को दो बार से अधिक दोहराते हुए पाते हैं, तो आप शायद किसी सुविधा से अनजान हैं।
रेगेक्स में, आप इसके लिए क्वांटिफायर का उपयोग कर सकते हैं। 11 अंकों का मिलान करने के लिए, आप केवल अभिव्यक्ति \d{11} लिख सकते हैं।
नीचे दी गई तालिका रेगेक्स में उपयोग किए जा सकने वाले क्वांटिफायर को सूचीबद्ध करती है:
क्वांटिफायरमिलान *0 या अधिक ?0 या 1 +1 या अधिक {n}ठीक n बार {n, }n या अधिक बार {n, m}n से m बार समावेशीइस उदाहरण में, अभिव्यक्ति can\s+write can के बाद 1 या अधिक व्हाइटस्पेस के बाद write से मेल खाती है। लेकिन आप देख सकते हैं कि 'canwrite' का मिलान नहीं होता क्योंकि \s+ का अर्थ है कम से कम एक व्हाइटस्पेस का मिलान होना आवश्यक है। यह तब उपयोगी होता है जब आप ऐसे टेक्स्ट को खोज रहे होते हैं जो ट्रिम नहीं किया गया हो।
क्या आप अनुमान लगा सकते हैं कि can\s?write क्या मिलान करेगा?
कैप्चर समूह
कैप्चर समूह उप-अभिव्यक्तियाँ हैं जिन्हें पैरेंथेसिस () में संलग्न किया जाता है। आपके पास कितने भी कैप्चर समूह हो सकते हैं, और यहां तक कि नेस्टेड कैप्चर समूह भी हो सकते हैं।
अभिव्यक्ति (The ){2} 'The ' से दो बार मेल खाती है। लेकिन कैप्चर समूह के बिना, अभिव्यक्ति The {2} 'The' के बाद 2 स्पेस से मेल खाएगी, क्योंकि क्वांटिफायर 'The ' को एक समूह के रूप में नहीं बल्कि स्पेस वर्ण पर लागू होगा।
आप कैप्चर समूह के अंदर किसी भी पैटर्न का मिलान वैसे ही कर सकते हैं जैसे आप किसी वैध रेगेक्स के साथ करेंगे। यहां (is\s+){2} मेल खाता है यदि यह 'is' के बाद 1 या अधिक स्पेस को दो बार ढूंढता है।
रेगेक्स में तार्किक OR का उपयोग कैसे करें
आप कई पैटर्न का मिलान करने के लिए "|" का उपयोग कर सकते हैं। This is (good|bad|sweet) 'This is ' के बाद 'good' या 'bad' या 'sweet' में से किसी से मेल खाता है।
फिर से, आपको यहां कैप्चर समूह के महत्व को समझना होगा। सोचें कि अभिव्यक्ति This is good|bad|sweet क्या मिलान करेगी?
कैप्चर समूह के साथ, good|bad|sweet This is से अलग हो जाता है। लेकिन अगर यह कैप्चर समूह के अंदर नहीं है, तो पूरा रेगेक्स केवल एक समूह है। इसलिए अभिव्यक्ति This is good|bad|sweet मेल खाएगी यदि स्ट्रिंग में 'This is good' या 'bad' या 'sweet' है।
कैप्चर समूहों को संदर्भित कैसे करें
कैप्चर समूहों को उसी अभिव्यक्ति में या प्रतिस्थापन करते समय संदर्भित किया जा सकता है जैसा कि आप Replacement टैब पर देख सकते हैं।
अधिकांश टूल और भाषाएं आपको nth कैप्चर किए गए समूह को '\n' के साथ संदर्भित करने की अनुमति देती हैं। इस साइट पर प्रतिस्थापन पर संदर्भित करते समय '$n' का उपयोग किया जाता है। प्रतिस्थापन के लिए सिंटैक्स आपके द्वारा उपयोग किए जा रहे टूल या भाषा के आधार पर भिन्न होगा। उदाहरण के लिए, जावास्क्रिप्ट के लिए, यह '$n' है, जबकि पायथन के लिए यह '\n' है।
अभिव्यक्ति (This) is \1 power में, 'This' कैप्चर किया जाता है और फिर '\1' के साथ संदर्भित किया जाता है, प्रभावी रूप से This is This power से मेल खाता है।
कैप्चर समूहों को नाम कैसे दें
आप अपने कैप्चर समूहों को सिंटैक्स (?<name>pattern) के साथ नाम दे सकते हैं और उन्हें उसी अभिव्यक्ति में \k<name> के साथ बैकरेफरेंस कर सकते हैं।
प्रतिस्थापन पर, संदर्भ $<name> द्वारा किया जाता है। यह जावास्क्रिप्ट के लिए सिंटैक्स है और भाषाओं के बीच भिन्न हो सकता है। आप यहां अंतर के बारे में जान सकते हैं। यह भी ध्यान दें कि यह सुविधा कुछ भाषाओं में उपलब्ध नहीं हो सकती है।
अभिव्यक्ति (?<lang>[\w+]+) is the best but \k<lang> .* में, पैटर्न [\w+]+ को 'lang' नाम से कैप्चर किया जाता है और \k<lang> के साथ बैकरेफरेंस किया जाता है। यह पैटर्न किसी भी वर्ड वर्ण या '+' वर्ण से 1 या अधिक बार मेल खाएगा। रेगेक्स के अंत में .* किसी भी वर्ण से 0 या अधिक बार मेल खाता है। और अंत में प्रतिस्थापन पर, संदर्भ $<lang> द्वारा किया जाता है।
अच्छे CLI टूल उपलब्ध हैं जो आपको अपने टर्मिनल से रेगेक्स करने देते हैं। ये टूल आपका और भी अधिक समय बचाते हैं क्योंकि आप कुछ भाषा में कोड लिखे बिना और फिर उसे संकलित या इंटरप्रेट किए बिना आसानी से विभिन्न रेगेक्स का परीक्षण कर सकते हैं।
कुछ प्रसिद्ध टूल हैं grep, sed, और awk। आइए कुछ उदाहरण देखें ताकि आपको अंदाजा हो सके कि आप इन टूल का लाभ कैसे उठा सकते हैं।
grep के साथ रिकर्सिव रेगेक्स खोज
आप grep के माध्यम से रेगेक्स की शक्ति निष्पादित कर सकते हैं। Grep किसी फ़ाइल में पैटर्न खोज सकता है या रिकर्सिव खोज कर सकता है।
यदि आप विंडोज पर हैं, तो आप winget का उपयोग करके grep इंस्टॉल कर सकते हैं। पावरशेल में यह कमांड चलाएं:
winget install -e --id GnuWin32.Grep
मैं आपको मेरे विश्वविद्यालय में एक CTF प्रतियोगिता के लिए बनाई गई एक चुनौती का समाधान दिखाऊंगा।
चुनौती से जुड़ी फ़ाइल एक ज़िप फ़ाइल है जिसमें कई स्तर की डायरेक्टरी और बहुत सारी फ़ाइलें हैं। प्रतियोगिता का नाम Coderush था जिसका फ्लैग फॉर्मेट coderush{flag is here} था। इसलिए आपको पैटर्न coderush{.*} खोजना होगा जो फ्लैग फॉर्मेट coderush{any character here} से मेल खाएगा।
unzip ripG.zip से फ़ाइल अनज़िप करें और cd ripG से इसमें जाएं।
358 डायरेक्टरी और 8731 फ़ाइलें हैं। पैटर्न को एक-एक करके फ़ाइलों में खोजने के बजाय, आप grep का उपयोग इस तरह कर सकते हैं:
grep --color -R "coderush{.*}"
"-R" फ्लैग रिकर्सिव खोज को सक्षम करता है।
आप यहां grep और इसके कमांड लाइन विकल्पों के बारे में अधिक जान सकते हैं
sed के साथ प्रतिस्थापन
आप टेक्स्ट फ़ाइलों पर सम्मिलन, विलोपन, प्रतिस्थापन करने के लिए रेगेक्स निर्दिष्ट करके sed का उपयोग कर सकते हैं। यदि आप विंडोज पर हैं, तो आप यहां से sed प्राप्त कर सकते हैं। या यदि आप WSL का उपयोग करते हैं, तो grep और sed जैसे टूल पहले से ही उपलब्ध होंगे।
यह sed का सबसे आम उपयोग है:
sed 's/pattern/replacement/g' filename echo "${text}" | sed 's/pattern/replacement/g'
यहां, सभी घटनाओं को बदलने के लिए विकल्प "g" निर्दिष्ट किया गया है।
कुछ अन्य उपयोगी विकल्प हैं -n सभी लाइनों को प्रिंट करने के डिफ़ॉल्ट व्यवहार को दबाने के लिए और g के बजाय p का उपयोग करके केवल उन लाइनों को प्रिंट करने के लिए जो रेगेक्स से प्रभावित होती हैं।
आइए texts.txt की सामग्री देखें।
Hello rand chars World 56 rand chars Henlo 52 rand chars W0rld rand chars GREP rand chars Henlo 62 rand chars Henlo 10 rand chars Henlo rand chars GREP rand chars Henlo 45 rand chars
हमारा कार्य Henlo नंबर को Hello नंबर से केवल उन लाइनों में बदलना है जहां "GREP" मौजूद है। तो, हम पैटर्न Henlo ([0-9]+) खोज रहे हैं जो 'Henlo ' के बाद 1 या अधिक अंकों से मेल खाएगा और सभी अंक कैप्चर हो जाएंगे। फिर हमारा प्रतिस्थापन स्ट्रिंग Hello \1 होगा - '\1' अंकों वाले कैप्चर समूह को संदर्भित कर रहा है।
इसे पूरा करने का एक तरीका उन लाइनों को grep करना होगा जिनमें "GREP" मौजूद है फिर sed के साथ प्रतिस्थापन करना।
grep "GREP" texts.txt | sed -En 's/Henlo ([0-9]+)/Hello \1/p'
"-E" विकल्प एक्सटेंडेड रेगेक्स को सक्षम करता है जिसके बिना आपको पैरेंथेसिस को एस्केप करना होगा।
या आप केवल sed का उपयोग कर सकते हैं। केवल उन लाइनों पर प्रतिस्थापन प्रतिबंधित करने के लिए /pattern/ का उपयोग करें जहां पैटर्न मौजूद है।
sed -En '/GREP/ s/Henlo ([0-9]+)/Hello \1/p' texts.txt
उन्नत रेगेक्स: लुकअराउंड
लुकअहेड और लुकबिहाइंड (एक साथ लुकअराउंड के रूप में जाने जाते हैं) रेगेक्स की ऐसी विशेषताएं हैं जो आपको पैटर्न के अस्तित्व की जांच करने की अनुमति देती हैं बिना उसे मिलान में शामिल किए।
आप उन्हें शून्य-चौड़ाई असर्शन के रूप में सोच सकते हैं - वे पैटर्न के अस्तित्व का दावा करते हैं लेकिन मिलान में किसी भी वर्ण का उपभोग नहीं करते। ये बहुत शक्तिशाली विशेषताएं हैं, लेकिन वे कम्प्यूटेशनली महंगी भी हैं। इसलिए यदि आप उनका अक्सर उपयोग कर रहे हैं तो प्रदर्शन पर नज़र रखना सुनिश्चित करें।
लुकबिहाइंड
मान लीजिए आप शब्द 'linux' का मिलान करना चाहते हैं, लेकिन आपकी 2 शर्तें हैं।
- 'GNU' शब्द 'linux' आने से पहले होना चाहिए। यदि कोई लाइन 'linux' रखती है लेकिन उसके पहले 'GNU' नहीं है, तो हम उस लाइन को अस्वीकार करना चाहते हैं।
- हम केवल
linuxका मिलान करना चाहते हैं और कुछ नहीं।
हम पहले से ही जानते हैं कि पहली शर्त को कैसे संतुष्ट किया जाए। GNU.* 'GNU' के बाद किसी भी संख्या में वर्णों से मेल खाएगा। फिर अंत में हम शब्द linux से मेल खाते हैं। यह GNU-any-characters-linux सभी से मेल खाएगा।
लेकिन हम GNU.* का मिलान कैसे रोकें जबकि पहली शर्त को बनाए रखें?
यहीं एक पॉजिटिव लुकबिहाइंड काम आता है। आप कैप्चर समूह को ?<= से पूर्वनिर्धारित करके पॉजिटिव लुकबिहाइंड के रूप में चिह्नित कर सकते हैं। इस उदाहरण में, अभिव्यक्ति (?<=GNU.*)linux बन जाती है।
अब केवल linux का मिलान होता है और कुछ नहीं।
ध्यान दें कि अभिव्यक्तियाँ (?<=GNU.*)linux और linux(?<=GNU.*) बिल्कुल समान व्यवहार करेंगी। दूसरी अभिव्यक्ति में, हालांकि linux लुकबिहाइंड से पहले है, 'GNU' के बाद .* है जो linux से मेल खाता है। इसका मतलब है कि यह लुकबिहाइंड को संतुष्ट करता है।
इसे सरल बनाने के लिए, लुकबिहाइंड के बिना पैटर्न के बारे में सोचें। पैटर्न GNU.* 'GNU' और उसके बाद कुछ भी मिलान करेगा, हमारे मामले में linux से मेल खाता है।
अब हम एक सामान्य कथन प्राप्त कर सकते हैं कि अभिव्यक्ति (?<=C)X पैटर्न X से मेल खाएगी - केवल तभी यदि पैटर्न C, X से पहले आया हो (और C को मिलान में शामिल नहीं किया जाना चाहिए)।
आप पहली शर्त को उलट भी सकते हैं। उन लाइनों का मिलान करें जिनमें शब्द linux है केवल यदि GNU कभी उसके पहले नहीं आया। इसे नेगेटिव लुकबिहाइंड कहा जाता है। इस मामले में उपसर्ग ?<! है। पिछली अभिव्यक्ति का व्युत्क्रम (?<!GNU.*)linux होगा।
लुकअहेड
लुकअहेड भी लुकबिहाइंड की तरह असर्शन हैं, जैसा कि आपने पिछले उदाहरण में देखा। एकमात्र अंतर यह है कि लुकबिहाइंड पहले असर्शन करते हैं और लुकअहेड बाद में असर्शन करते हैं।
मान लीजिए आपकी ये दो शर्तें हैं:
Helloका मिलान केवल तभी करें यदिWorldइसके बाद कहीं आता है।- केवल Hello का मिलान करें और कुछ नहीं।
पॉजिटिव लुकअहेड के लिए उपसर्ग ?= है। अभिव्यक्ति Hello(?=.*World) दोनों शर्तों को पूरा करेगी। यह Hello.*World के समान है सिवाय इसके कि केवल Hello का मिलान होगा जबकि Hello.*World 'Hello', 'World' और बीच में कुछ भी मिलान करेगा।
पॉजिटिव लुकबिहाइंड के उदाहरण के समान, अभिव्यक्तियाँ Hello(?=.*World) और (?=.*World)Hello समतुल्य हैं। क्योंकि 'World' से पहले .* Hello से मेल खाता है, पहली शर्त को संतुष्ट करता है।
नेगेटिव लुकअहेड नेगेटिव लुकबिहाइंड का पूरक है। आप इसे ?! से पूर्वनिर्धारित करके उपयोग कर सकते हैं। (?!World)Hello Hello से केवल तभी मेल खाएगा यदि उसके बाद कहीं भी World नहीं है।
यहां लुकअराउंड के सिंटैक्स का सारांश दिया गया है जब आप असर्शन C के साथ पैटर्न X का मिलान करना चाहते हैं।
ऑपरेशनRegEx पॉजिटिव लुकअहेड(?=C)X नेगेटिव लुकअहेड(?!C)X पॉजिटिव लुकबिहाइंड(?<=C)X नेगेटिव लुकबिहाइंड(?<!C)X लॉग पार्सिंग
इस लॉग फ़ाइल में, ये वे लाइनें हैं जिनकी हमें परवाह है:
[1/10000] Train loss: 11.30368, Valid loss: 8.95446, Elapsed_time: 7.58941 [500/10000] Train loss: 0.96180, Valid loss: 0.20098, Elapsed_time: 82.48651 [1000/10000] Train loss: 0.04051, Valid loss: 0.11927, Elapsed_time: 156.86243
हमारा कार्य प्रशिक्षण हानि और सत्यापन हानि को निकालना है ताकि ईपोक पर हानि को प्लॉट करने जैसे उद्देश्यों के लिए उपयोग किया जा सके। हमें 11.30368, 0.96180, 0.04051 जैसे प्रशिक्षण हानि मान निकालने और उन्हें एक सरणी में रखने की आवश्यकता है।
सभी प्रासंगिक मान 'Train loss:' से पूर्वनिर्धारित हैं, इसलिए हम इसे अपने रेगेक्स में वैसे ही उपयोग कर सकते हैं। फ्लोट नंबरों का मिलान करने के लिए हमें कुछ अंकों का मिलान करना होगा फिर एक "." और फिर और अंक। आप इसे \d+\.\d+ से कर सकते हैं। क्योंकि हम इन नंबरों को ट्रैक करना चाहते हैं, उन्हें कैप्चर समूह के अंदर होना चाहिए।
चूंकि "." का रेगेक्स में विशेष उद्देश्य है, जब आप "." वर्ण का मिलान करना चाहते हैं तो आपको इसे बैकस्लैश से एस्केप करना होगा। यह सभी विशेष उद्देश्य वाले वर्णों के लिए लागू होता है। लेकिन आपको इसे वर्ण सेट के अंदर एस्केप करने की आवश्यकता नहीं है।
इसे एक साथ रखते हुए, प्रशिक्षण हानि निकालने के लिए अभिव्यक्ति Train loss: (\d+\.\d+) है। हम सत्यापन हानि निकालने के लिए उसी तर्क का उपयोग कर सकते हैं Valid loss: (\d+\.\d+) के साथ।
यहां पायथन का उपयोग करके इस जानकारी को निकालने का एक तरीका है:
import re f = open("log_train.txt", "r").read() train_loss = re.findall(r'Train loss: (\d+\.\d+)', f) valid_loss = re.findall(r'Valid loss: (\d+\.\d+)', f) train_loss = [float(i) for i in train_loss] valid_loss = [float(i) for i in valid_loss] print("train_loss =", train_loss) print("") print("valid_loss =", valid_loss)
जब एक कैप्चर समूह होता है, तो re.findall सभी लाइनों को खोजता है और कैप्चर समूह के अंदर के मानों को एक सूची में वापस करता है।
कोई भी रेगेक्स फ़ंक्शन केवल स्ट्रिंग्स वापस करता है, इसलिए मानों को फ्लोट में बदलकर प्रिंट किया जाता है। फिर आप उन्हें सीधे फ्लोट की सूची के रूप में किसी अन्य पायथन स्क्रिप्ट में उपयोग कर सकते हैं।
यह परिणाम है:
आप sed का उपयोग भी कर सकते हैं, आउटपुट को train_losses.txt में सहेजें, और फ़ाइल से पढ़ें। पहले हम '/Train/' का उपयोग करके केवल 'Train' वाली लाइनों को लक्षित करते हैं फिर हम पहले जैसे ही रेगेक्स लागू करते हैं।
sed -En '/Train/ s/.*Train loss: ([0-9]+\.[0-9]+).*/\1/p' log_train.txt | tee train_losses.txt
".*" को शुरुआत और अंत में जोड़ा गया है ताकि sed सभी प्रासंगिक लाइनों की सामग्री से मेल खा सके। फिर पूरी लाइन को कैप्चर समूह के मान से बदल दिया जाता है। tee कमांड का उपयोग sed के आउटपुट को train_losses.txt में रीडायरेक्ट करने के साथ-साथ टर्मिनल में सामग्री प्रिंट करने के लिए किया जाता है।
एक पल के लिए सोचें कि ईपोक निकालने के लिए आपको क्या चाहिए। आपको [500/10000] से 500 निकालना होगा ऐसी सभी लाइनों के लिए। सरणी [1, 500, 1000, 1500, ...] की तरह दिखनी चाहिए। आप पिछले उदाहरण के समान दृष्टिकोण का पालन कर सकते हैं।
ध्यान दें कि यदि आप "[" या "]" का मिलान करना चाहते हैं, तो आपको इसे एस्केप करना होगा। उत्तर यहां दिया गया है।
बल्क फ़ाइल नाम बदलना
आपके पास कुछ यादृच्छिक मानों को प्रीफिक्स के रूप में ये फ़ाइलें हैं। आपको सभी फ़ाइलों का नाम 1.mp4, 2.mp4 इत्यादि के रूप में बदलना है। इस तरह फ़ाइलें उत्पन्न की गई थीं।
यह एक सामान्य परिदृश्य है जहां आपके पास फ़ाइलों की एक सूची होती है जिनके नाम में उनका क्रम संख्या होता है लेकिन कुछ अन्य वर्ण भी होते हैं जो आप नहीं चाहते।
पैटर्न को Episode तक कुछ भी मिलान करना होगा फिर एक अंडरस्कोर और फिर नंबर और अंत में .mp4।
प्रासंगिक मान '.mp4' से पहले की संख्या है जिसे हम कैप्चर समूह में रखेंगे। .*Episode_ नंबर तक सब कुछ मिलान करेगा। फिर हम ([0-9]+) से नंबर कैप्चर कर सकते हैं और \.mp4 से .mp4 भी मिलान कर सकते हैं।
तो अंतिम रेगेक्स है .*Episode_([0-9]+)\.mp4। चूंकि हम .mp4 रखना चाहते हैं, प्रतिस्थापन स्ट्रिंग \1.mp4 होगी।
यह sed का उपयोग करके इसे हल करने का एक तरीका है।
for i in *.mp4; do newname=$(echo $i | sed -En 's/.*Episode_([0-9]+)\.mp4/\1.mp4/p') mv $i $newname done;ls
पहले नया नाम एक वेरिएबल में सहेजा जाता है और फिर फ़ाइल का नाम बदलने के लिए mv कमांड का उपयोग किया जाता है।
क्या हम .*Episode_ के स्थान पर केवल .* का उपयोग कर सकते थे? इस उदाहरण में, हाँ। लेकिन Steins_Gate0.mp4 जैसे फ़ाइल नाम हो सकते हैं जहां 0 मूवी नाम का हिस्सा है और आप वास्तव में इस फ़ाइल का नाम नहीं बदलना चाहते थे इसलिए हमेशा यथासंभव विशिष्ट होना बेहतर है।
क्या होगा यदि कुछ फ़ाइलों के नाम "Random_Episode6.mp4" थे? अंतर यह है कि Episode के बाद कोई अंडरस्कोर नहीं है। आपको क्या बदलाव करने की आवश्यकता होगी?
उत्तर यह है कि आपको "_" के बाद "?" जोड़कर इसे वैकल्पिक बनाना होगा। रेगेक्स होगा .*Episode_?([0-9]+)\.mp4।
ईमेल सत्यापन
ईमेल सत्यापन के लिए सभी प्रकार के जटिल रेगेक्स हैं।
यहां एक सरल है: ^[^@ ]+@[^@.]+\.\w+$। यह फॉर्मेट A@B.C से मेल खाता है
नीचे दी गई तालिका इस पैटर्न को छोटे टुकड़ों में तोड़ती है:
पैटर्नमिलान^लाइन की शुरुआत [^@ ]+"@" और स्पेस वर्ण को छोड़कर कुछ भी @[^@.]+@ के बाद "@" और "." वर्ण को छोड़कर कुछ भी \.\w+"." के बाद वर्ड वर्ण $लाइन का अंत regexr साइट पर, आप ऊपरी दाएं कोने में Flags टैब से मल्टीलाइन फ्लैग सक्षम कर सकते हैं। अंत में 'gm' इंगित करता है कि मल्टीलाइन फ्लैग सक्षम है।
हम देख सकते हैं कि लाइन 2,3,5,6 मेल नहीं खाईं। क्या आप कारण ढूंढ सकते हैं और रेगेक्स का कौन सा हिस्सा इसे अयोग्य ठहराने के लिए जिम्मेदार है?
उत्तर यहां दिया गया है
पासवर्ड बाधाएं
आप बाधाएं लगाने के लिए रेगेक्स का उपयोग भी कर सकते हैं। यहां हम पॉजिटिव लुकअहेड की शक्ति को उजागर करेंगे।
मान लीजिए हम एक स्ट्रिंग को तभी स्वीकार करना चाहते हैं यदि उसमें एक अंक है। आप पहले से ही जानते हैं कि '\d' वर्ग से अंक कैसे ढूंढें। इसे पूरा करने के लिए, हम [^\d]*\d का उपयोग कर सकते हैं। यह किसी भी नॉन-डिजिट वर्ण से 0 या अधिक बार मेल खाएगा और फिर एक डिजिट से मेल खाएगा।
हम अभिव्यक्ति .*\d का उपयोग एक अंक का मिलान करने के लिए भी कर सकते हैं। इसलिए यदि स्ट्रिंग में कोई अंक नहीं है तो लुकअहेड विफल हो जाएगा और उस स्ट्रिंग के कोई भी वर्ण मेल नहीं खाएंगे, एक खाली स्ट्रिंग "" वापस कर देंगे।
जब हम प्रोग्रामिंग भाषा का उपयोग कर रहे होते हैं, तो हम जांच सकते हैं कि क्या रेगेक्स ने खाली स्ट्रिंग वापस की और निर्धारित कर सकते हैं कि बाधाएं संतुष्ट नहीं हैं।
हम एक रेगेक्स बनाएंगे जो निम्नलिखित मानदंड लागू करता है:
- न्यूनतम 8 वर्ण और अधिकतम 16 वर्ण।
- कम से कम एक लोअरकेस अक्षर।
- कम से कम एक अपरकेस अक्षर।
- कम से कम एक संख्या।
इसे प्राप्त करने के लिए, आप पॉजिटिव लुकअहेड का उपयोग कर सकते हैं। यह रेगेक्स है:
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,16}$
नीचे दी गई तालिका बताती है कि रेगेक्स का कौन सा हिस्सा कौन सी बाधा लागू करता है:
पैटर्नलागू बाधा.{8,16}न्यूनतम 8 और अधिकतम 16 वर्ण (?=.*[a-z])न्यूनतम एक लोअरकेस अक्षर (?=.*[A-Z])न्यूनतम एक अपरकेस अक्षर (?=.*\d)न्यूनतम एक अंक कम से कम 5 अपरकेस अक्षरों को लागू करने के लिए आपको क्या संशोधन करने की आवश्यकता होगी?
आप सोच सकते हैं (?=.*[A-Z]{5,}) काम करेगा। लेकिन इस अभिव्यक्ति के लिए सभी 5 अक्षरों का एक साथ होना आवश्यक है। rand-ABCDE-rand जैसा स्ट्रिंग मिलान होगा लेकिन 0AxBCDxE0 नहीं मिलान होगा भले ही इसमें 5 अपरकेस अक्षर हों (क्योंकि वे आसन्न नहीं हैं)।
फिर भी, कैप्चर समूह बचाव में आते हैं। हम स्ट्रिंग में कहीं भी 5 अपरकेस अक्षरों का मिलान करना चाहते हैं। हम पहले से ही जानते हैं कि हम .*[A-Z] से 1 अपरकेस अक्षर का मिलान कर सकते हैं। अब हम उन्हें कैप्चर समूह के अंदर रखेंगे और न्यूनतम 5 का क्वांटिफायर जोड़ देंगे। अभिव्यक्ति होगी (.*[A-Z]){5,}।
यहां अंतिम उत्तर है:
(?=.*[A-Z]) के स्थान पर आपको (?=(.*[A-Z]){5,}) की आवश्यकता होगी। अभिव्यक्ति बन जाती है ^(?=.*[a-z])(?=(.*[A-Z]){5,})(?=.*\d).{8,16}$।
आप यह भी मांग कर सकते हैं कि पासवर्ड में कुछ शब्द न हों ताकि मजबूत पासवर्ड लागू किए जा सकें।
उदाहरण के लिए, हम पासवर्ड को अस्वीकार करना चाहते हैं यदि इसमें pass या 1234 है। इस काम के लिए नेगेटिव लुकअहेड उपकरण है। रेगेक्स होगा ^(?!.*(pass|1234)).*$।
इस रेगेक्स में, हमने pass और 1234 को कैप्चर समूह के अंदर रखा और तार्किक OR ऑपरेटर का उपयोग किया। यह कैप्चर समूह दूसरे कैप्चर समूह के अंदर नेस्टेड है जिसे ?!.* से पूर्वनिर्धारित किया गया है। यह इसे एक नेगेटिव लुकअहेड बनाता है जो कम से कम 8 वर्णों .{8,} से मेल खाता है इस शर्त के साथ कि, pass या 1234 स्ट्रिंग में कहीं भी मौजूद नहीं हो सकते।
अंतिम शब्द
मुझे आशा है कि इस लेख को पढ़ते समय आपको अच्छा अभ्यास मिला होगा। यदि आप कुछ सिंटैक्स भूल जाते हैं तो कोई बात नहीं। महत्वपूर्ण बात मूल अवधारणाओं को समझना और यह जानना है कि रेगेक्स के साथ क्या संभव है। फिर, यदि आप कोई पैटर्न भूल जाते हैं, तो आप बस गूगल कर सकते हैं या चीटशीट देख सकते हैं।
जितना अधिक आप अभ्यास करेंगे, उतना ही आप बाहरी मदद के बिना काम कर पाएंगे। अंततः आप पूरी तरह से ऑफलाइन सुपर जटिल और प्रभावी रेगेक्स लिखने में सक्षम होंगे।
बाहर पहले से ही कुछ अच्छी रेगेक्स चीटशीट हैं, इसलिए मैं यहां कुछ अधिक गहराई वाला बनाना चाहता था जिसे आप मूल अवधारणाओं और सामान्य उपयोग के मामलों के लिए संदर्भित कर सकें।
यदि आप चीटशीट ढूंढ रहे हैं, तो QuickRef की वाली मददगार है। यह सिंटैक्स याद करने के लिए एक अच्छी जगह है और वे विभिन्न प्रोग्रामिंग भाषाओं में रेगेक्स से संबंधित फ़ंक्शन का बुनियादी अवलोकन भी प्रदान करते हैं।
अधिकांश रेगेक्स तकनीकें सभी प्रोग्रामिंग भाषाओं और टूल में समान हैं - लेकिन कुछ टूल अतिरिक्त सुविधाएं प्रदान कर सकते हैं। इसलिए जिस टूल का आप उपयोग कर रहे हैं उस पर कुछ शोध करें ताकि आपके लिए सबसे अच्छा चुना जा सके।
मेरा अंतिम सुझाव होगा कि सिर्फ इसलिए रेगेक्स का उपयोग करने के लिए मजबूर न हों क्योंकि आप कर सकते हैं। कई बार एक साधारण string.find() काम पूरा करने के लिए पर्याप्त होता है। लेकिन यदि आप टर्मिनल में रहते हैं, तो आप वास्तव में निश्चित रूप से रेगेक्स के साथ बहुत कुछ कर सकते हैं।
यदि आपको इस प्रकार का लेख पसंद है, तो आप मेरे ब्लॉग या ट्विटर पर नज़र रख सकते हैं।
मुफ्त में कोड करना सीखें। freeCodeCamp के ओपन सोर्स पाठ्यक्रम ने 40,000 से अधिक लोगों को डेवलपर के रूप में नौकरी पाने में मदद की है। शुरू करें