हंस, मैं चारा और मांस को अपने पहले के उत्तर से निकालूंगा। आपने कहा कि आप "कुछ अधिक पूर्ण" चाहते हैं, इसलिए मुझे आशा है कि आप लंबे उत्तर को ध्यान में नहीं रखेंगे - कृपया प्रसन्न करने की कोशिश करेंगे। चलो कुछ पृष्ठभूमि के साथ शुरू करते हैं।
सबसे पहले, यह एक उत्कृष्ट सवाल है। कुछ संदर्भों (उदाहरण के लिए, एक कोड ब्लॉक के भीतर या कोष्ठक के भीतर) को छोड़कर कुछ पैटर्न के मिलान के बारे में अक्सर सवाल होते हैं। ये प्रश्न अक्सर काफी अजीब समाधानों को जन्म देते हैं। इसलिए कई संदर्भों के बारे में आपका प्रश्न एक विशेष चुनौती है।
आश्चर्य
आश्चर्यजनक रूप से, कम से कम एक कुशल समाधान है जो सामान्य है, लागू करना आसान है और बनाए रखने के लिए एक खुशी है। यह सभी रेगेक्स फ्लेवर के साथ काम करता है जो आपको अपने कोड में कैप्चर समूहों का निरीक्षण करने की अनुमति देता है। और यह कई सामान्य सवालों के जवाब देने के लिए होता है जो पहली बार आपसे अलग लग सकते हैं: "डोनट्स को छोड़कर सब कुछ मैच करें", "सभी को बदलें लेकिन ...", "मेरी माँ की काली सूची को छोड़कर सभी शब्दों को मिलाएं", "अनदेखा करें टैग "," तापमान मिलान जब तक italicized "...
अफसोस की बात है, तकनीक अच्छी तरह से ज्ञात नहीं है: मेरा अनुमान है कि बीस एसओ प्रश्नों में जो इसका उपयोग कर सकते हैं, केवल एक के पास एक उत्तर है जो इसका उल्लेख करता है - जिसका अर्थ है कि शायद पचास या साठ उत्तरों में से एक। टिप्पणियों में कोबी के साथ मेरा आदान-प्रदान देखें। इस लेख में तकनीक को कुछ गहराई से वर्णित किया गया है जो इसे (आशावादी रूप से) "सर्वश्रेष्ठ रेगेक्स ट्रिक" कहता है। ज्यादा विस्तार में जाने के बिना, मैं आपको यह बताने की कोशिश करूंगा कि तकनीक कैसे काम करती है। विभिन्न भाषाओं में अधिक विस्तार और कोड नमूनों के लिए मैं आपको उस संसाधन से परामर्श करने के लिए प्रोत्साहित करता हूं।
एक बेहतर-ज्ञात विविधता
पर्ल और PHP के लिए सिंटैक्स विशिष्ट का उपयोग करके एक भिन्नता है जो समान है। आप इस तरह के रूप में रेगुलर एक्सप्रेशन से स्वामी के हाथ में इतने पर यह देखेंगे CasimiretHippolyte और हमजा । मैं आपको इसके बारे में और नीचे बताऊंगा, लेकिन यहां मेरा ध्यान सामान्य समाधान पर है जो सभी regex जायके के साथ काम करता है (जब तक आप अपने कोड में कैप्चर समूहों का निरीक्षण कर सकते हैं)।
सभी पृष्ठभूमि के लिए धन्यवाद, zx81 ... लेकिन नुस्खा क्या है?
मुख्य तथ्य
विधि समूह 1 कैप्चर में मैच लौटाती है। यह समग्र मैच के बारे में बिल्कुल भी परवाह नहीं करता है।
वास्तव में, ट्रिक उन विभिन्न संदर्भों से मेल खाती है , जिन्हें हम नहीं चाहते हैं ( |या संदर्भ / विकल्प का उपयोग करके इन संदर्भों का पीछा करते हुए ) ताकि "उन्हें बेअसर कर सकें"। सभी अवांछित संदर्भों के मिलान के बाद, प्रत्यावर्तन के अंतिम भाग से हम क्या चाहते हैं और इसे समूह 1 में कैप्चर करता है।
सामान्य नुस्खा है
Not_this_context|Not_this_either|StayAway|(WhatYouWant)
यह मैच करेगा Not_this_context, लेकिन इस मायने में कि मैच एक कचरा बिन में चला जाता है, क्योंकि हम समग्र मैचों को नहीं देखेंगे: हम केवल ग्रुप 1 कैप्चर को देखते हैं।
आपके मामले में, आपके अंकों और आपके तीन संदर्भों को अनदेखा करने के लिए, हम कर सकते हैं:
s1|s2|s3|(\b\d+\b)
ध्यान दें कि क्योंकि हम वास्तव में s1, s2 और s3 से मिलते-जुलते हैं, ताकि वे लुकरॉइड्स से बचने की कोशिश कर रहे हैं, s1, s2 और s3 के लिए अलग-अलग भाव दिन के रूप में स्पष्ट रह सकते हैं। (वे प्रत्येक के उप भाग हैं |)
पूरी अभिव्यक्ति को इस तरह लिखा जा सकता है:
(?m)^.*\.$|\([^\)]*\)|if\(.*?//endif|(\b\d+\b)
यह डेमो देखें (लेकिन निचले दाएं फलक में कैप्चर समूहों पर ध्यान केंद्रित करें।)
यदि आप मानसिक रूप से प्रत्येक रेमीटर पर इस रेगेक्स को विभाजित करने की कोशिश करते हैं |, तो यह वास्तव में केवल चार बहुत ही सरल अभिव्यक्तियों की एक श्रृंखला है।
फ्री-स्पेसिंग का समर्थन करने वाले स्वादों के लिए, यह विशेष रूप से अच्छी तरह से पढ़ता है।
(?mx)
### s1: Match line that ends with a period ###
^.*\.$
| ### OR s2: Match anything between parentheses ###
\([^\)]*\)
| ### OR s3: Match any if(...//endif block ###
if\(.*?//endif
| ### OR capture digits to Group 1 ###
(\b\d+\b)
यह असाधारण रूप से पढ़ने और बनाए रखने में आसान है।
रेगेक्स का विस्तार
जब आप अधिक स्थितियों को s4 और s5 को अनदेखा करना चाहते हैं, तो आप उन्हें बाईं ओर अधिक विकल्पों में जोड़ते हैं:
s4|s5|s1|s2|s3|(\b\d+\b)
यह कैसे काम करता है?
जिन संदर्भों को आप नहीं चाहते हैं, उन्हें बाईं ओर के विकल्पों की सूची में जोड़ा जाता है: वे मेल खाएंगे, लेकिन इन समग्र मैचों की कभी जांच नहीं की जाती है, इसलिए उनका मिलान करना उन्हें "कचरा बिन" में डालने का एक तरीका है।
हालाँकि आप जो सामग्री चाहते हैं, वह ग्रुप 1 पर कब्जा कर ली गई है। फिर आपको प्रोग्रामेटिक रूप से यह देखना होगा कि ग्रुप 1 सेट है और खाली नहीं है। यह एक तुच्छ प्रोग्रामिंग कार्य है (और हम बाद में बात करेंगे कि यह कैसे किया जाता है), विशेष रूप से यह देखते हुए कि यह आपको एक सरल रीगेक्स के साथ छोड़ देता है जिसे आप एक नज़र में समझ सकते हैं और आवश्यकतानुसार संशोधित या विस्तारित कर सकते हैं।
मैं हमेशा विज़ुअलाइज़ेशन का प्रशंसक नहीं हूं, लेकिन यह दिखाने का एक अच्छा काम करता है कि विधि कितनी सरल है। प्रत्येक "लाइन" एक संभावित मैच से मेल खाती है, लेकिन केवल निचला रेखा समूह 1 में कब्जा कर लिया गया है।

डीबगेजक्स डेमो
पर्ल / पीसीआर भिन्नता
ऊपर दिए गए सामान्य समाधान के विपरीत, पर्ल और पीसीआरई के लिए भिन्नता मौजूद है जो अक्सर SO पर देखी जाती है, कम से कम regex Gods जैसे @CasimiretHippolyte और @ HamZa के हाथों में। यह है:
(?:s1|s2|s3)(*SKIP)(*F)|whatYouWant
आपके मामले में:
(?m)(?:^.*\.$|\([^()]*\)|if\(.*?//endif)(*SKIP)(*F)|\b\d+\b
यह भिन्नता उपयोग करने में थोड़ी आसान है क्योंकि संदर्भों s1, s2 और s3 में मिलान की गई सामग्री बस छोड़ दी जाती है, इसलिए आपको समूह 1 कैप्चर (कोष्ठक हट गए हैं) का निरीक्षण करने की आवश्यकता नहीं है। मैच केवल होते हैंwhatYouWant
ध्यान दें (*F), (*FAIL)और (?!)सभी एक ही चीज हैं। यदि आप अधिक अस्पष्ट होना चाहते हैं, तो आप उपयोग कर सकते हैं(*SKIP)(?!)
इस संस्करण के लिए डेमो
अनुप्रयोग
यहां कुछ सामान्य समस्याएं हैं जिन्हें यह तकनीक अक्सर आसानी से हल कर सकती है। आप देखेंगे कि शब्द का चुनाव इन समस्याओं में से कुछ को अलग कर सकता है जबकि वास्तव में वे वास्तव में समान हैं।
- मैं टैग जैसे टैग को छोड़कर कहीं से भी कैसे मैच कर सकता हूं
<a stuff...>...</a>?
- मैं
<i>टैग या जावास्क्रिप्ट स्निपेट (अधिक शर्तों) को छोड़कर फू से कैसे मिलान कर सकता हूं ?
- मैं उन सभी शब्दों से कैसे मेल कर सकता हूं जो इस ब्लैक लिस्ट में नहीं हैं?
- मैं किसी SUB ... END SUB ब्लॉक के अंदर कुछ भी कैसे अनदेखा कर सकता हूं?
- मैं सब कुछ कैसे मिला सकता हूं ... s1 s2 s3?
ग्रुप 1 कैप्चर को कैसे प्रोग्राम करें
आप कोड के लिए नहीं थे, लेकिन, पूरा होने के लिए ... समूह 1 का निरीक्षण करने के लिए कोड स्पष्ट रूप से आपकी पसंद की भाषा पर निर्भर करेगा। किसी भी दर पर यह उस कोड की एक जोड़ी से अधिक नहीं जोड़ना चाहिए जिस कोड का आप मैचों का निरीक्षण करेंगे।
यदि संदेह है, तो मैं आपको पहले उल्लेखित लेख के कोड नमूने अनुभाग को देखने की सलाह देता हूं , जो काफी कुछ भाषाओं के लिए कोड प्रस्तुत करता है।
वैकल्पिक
प्रश्न की जटिलता पर निर्भर करता है, और इस्तेमाल किए गए रेगेक्स इंजन पर, कई विकल्प हैं। यहाँ दो हैं जो कई स्थितियों सहित अधिकांश स्थितियों पर लागू हो सकते हैं। मेरे विचार में, न तो s1|s2|s3|(whatYouWant)नुस्खा के रूप में लगभग आकर्षक है , अगर केवल इसलिए कि स्पष्टता हमेशा जीतती है।
1. बदलें तो मैच।
एक अच्छा समाधान जो हैकिंग लगता है लेकिन कई वातावरणों में अच्छी तरह से काम करता है दो चरणों में काम करना है। पहला रेगेक्स उस संदर्भ को बेअसर कर देता है जिसे आप संभावित रूप से परस्पर विरोधी तार को बदलकर अनदेखा करना चाहते हैं। यदि आप केवल मैच करना चाहते हैं, तो आप एक खाली स्ट्रिंग के साथ बदल सकते हैं, फिर दूसरे चरण में अपना मैच चला सकते हैं। यदि आप बदलना चाहते हैं, तो आप पहले कुछ विशिष्ट के साथ नजरअंदाज किए जाने वाले तारों को बदल सकते हैं, उदाहरण के लिए, एक निश्चित-चौड़ाई श्रृंखला के साथ अपने अंकों के आसपास @@@। इस प्रतिस्थापन के बाद, आप वास्तव में जो चाहते थे, उसे बदलने के लिए स्वतंत्र हैं, फिर आपको अपने विशिष्ट @@@तारों को वापस करना होगा ।
2. लुकरॉइड्स।
आपकी मूल पोस्ट से पता चला है कि आप समझते हैं कि लुकरॉइड्स का उपयोग करके किसी एकल शर्त को कैसे छोड़ना है। आपने कहा कि C # इसके लिए महान है, और आप सही हैं, लेकिन यह एकमात्र विकल्प नहीं है। उदाहरण के लिए C #, VB.NET और Visual C ++ में पाए गए .NET regex फ्लेवर, साथ ही पायथन में regexबदलने के लिए अभी भी-प्रायोगिक मॉड्यूल re, केवल दो इंजन हैं जो मुझे पता है कि अनंत-चौड़ाई लुकअप का समर्थन करते हैं। इन उपकरणों के साथ, एक लुकबाइंड में एक स्थिति न केवल पीछे बल्कि मैच पर और मैच से परे देखने का ध्यान रख सकती है, एक लुकहेड के साथ समन्वय करने की आवश्यकता से बचती है। अधिक शर्तें? और अधिक लुक।
सी # में s3 के लिए आपके पास regex को रीसायकल करने से पूरा पैटर्न इस तरह दिखेगा।
(?!.*\.)(?<!\([^()]*(?=\d+[^)]*\)))(?<!if\(\D*(?=\d+.*?//endif))\b\d+\b
लेकिन अब तक आप जानते हैं कि मैं इसकी सिफारिश नहीं कर रहा हूँ, है ना?
हटाए
@ HamZa और @Jerry ने सुझाव दिया है कि मैं उन मामलों के लिए एक अतिरिक्त चाल का उल्लेख करता हूं जब आप बस हटाना चाहते हैं WhatYouWant। आपको याद है कि मैच के लिए नुस्खा WhatYouWant(ग्रुप 1 में कैप्चर करना) था s1|s2|s3|(WhatYouWant), है ना? के सभी उदाहरण को हटाने के लिए WhatYouWant, आप regex को बदल देते हैं
(s1|s2|s3)|WhatYouWant
प्रतिस्थापन स्ट्रिंग के लिए, आप उपयोग करते हैं $1। यहाँ क्या होता है कि प्रत्येक उदाहरण के s1|s2|s3लिए मिलान किया जाता है, प्रतिस्थापन $1उस उदाहरण को स्वयं के साथ बदल देता है (द्वारा संदर्भित $1)। दूसरी ओर, जब WhatYouWantमिलान किया जाता है, तो इसे एक खाली समूह द्वारा बदल दिया जाता है और कुछ नहीं - और इसलिए हटा दिया जाता है। इस अद्भुत दृश्य के सुझाव के लिए यह डेमो देखें , @ HamZa और @Jerry धन्यवाद।
प्रतिस्थापन
यह हमें प्रतिस्थापन में लाता है, जिस पर मैं संक्षेप में स्पर्श करूंगा।
- कुछ नहीं के साथ प्रतिस्थापित करते समय, ऊपर "हटाएं" चाल देखें।
- प्रतिस्थापित करते समय, यदि पर्ल या पीसीआरई का उपयोग किया जाता है, तो
(*SKIP)(*F)ऊपर उल्लिखित भिन्नता का उपयोग ठीक उसी तरह से करें जैसा आप चाहते हैं, और सीधे प्रतिस्थापन करें।
- अन्य फ्लेवर में, रिप्लेसमेंट फंक्शन कॉल के भीतर, कॉलबैक या लैम्ब्डा का उपयोग करके मैच का निरीक्षण करें, और यह बदलें कि क्या ग्रुप 1 सेट है। यदि आपको इसकी सहायता की आवश्यकता है, तो पहले से संदर्भित लेख आपको विभिन्न भाषाओं में कोड देगा।
मज़े करो!
नहीं, रुको, और भी है!
आह, नाह, मैं बीस संस्मरणों में अपने संस्मरणों के लिए, अगले वसंत को रिलीज़ होने के लिए बचत करूँगा।
\Kकोई विशेष php सिंटैक्स नहीं है। कृपया विस्तृत करें और स्पष्ट करें कि आप क्या कहना चाहते हैं। यदि आप हमें यह बताने के लिए लक्ष्य रखते हैं कि आपको "जटिल" समाधान की आवश्यकता नहीं है, तो आपको यह कहना होगा कि आपके लिए और क्यों जटिल है।