दोनों के बीच क्या अंतर है ?:, ?! और? = रेगेक्स में?


106

मैंने इन अभिव्यक्तियों के अर्थ की खोज की, लेकिन उनके बीच के सटीक अंतर को नहीं समझ सका। यह वे कहते हैं:

  • ?: अभिव्यक्ति का मिलान करें लेकिन इसे कैप्चर न करें।
  • ?= एक प्रत्यय का मिलान करें लेकिन इसे कैप्चर से बाहर रखें।
  • ?! मैच अगर प्रत्यय अनुपस्थित है।

मैं सरल RegEx में इन का उपयोग करने की कोशिश की और सभी के लिए समान परिणाम मिला। उदाहरण: निम्नलिखित 3 भाव बहुत समान परिणाम देते हैं।

  • [a-zA-Z0-9._-]+@[a-zA-Z0-9-]+(?!\.[a-zA-Z0-9]+)*
  • [a-zA-Z0-9._-]+@[a-zA-Z0-9-]+(?=\.[a-zA-Z0-9]+)*
  • [a-zA-Z0-9._-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9]+)*

कृपया हमें अपना परीक्षण मामला दिखाएं। उन्हें समान परिणाम नहीं देने चाहिए।
बरगी

@ sepp2k, यह कुछ मामलों में समान परिणाम देता है, उनमें से एक प्रश्न में वर्णित है।
आरके पोद्दार

@Bergi, मैंने इसे यादृच्छिक डेटा के साथ परीक्षण किया, जिसमें अंग्रेजी शब्द, फोन नंबर, यूआरएल, ई-मेल पते, नंबर आदि शामिल हैं।
आरके पोद्दार

4
@ रकारवाल आह, मैं देखता हूं कि आपने वहां क्या किया। आपने *समूहों के बाद जोड़ा , इसलिए उन्हें आसानी से अनदेखा कर दिया गया।
sepp2k

noobie नोट : आप केवल कोष्ठक की शुरुआत में इनका उपयोग करेंगे, और कोष्ठक एक कैप्चरिंग समूह (अलग-अलग कोष्ठक पाठ के विभिन्न वर्गों को निकालने के लिए सेट) बनाते हैं।
रयान टेलर

जवाबों:


150

के बीच का अंतर ?=और ?!है कि पूर्व मिलान करने के लिए दिए गए अभिव्यक्ति की आवश्यकता है और बाद में यह करने के लिए की आवश्यकता है नहीं मेल खाते हैं। उदाहरण के लिए a(?=b)"ए" में "ए" का मिलान होगा, लेकिन "एसी" में "ए" का नहीं। जबकि a(?!b)"एसी" में "ए" का मिलान होगा, लेकिन "ए" में "ए" का नहीं।

के बीच का अंतर ?:और ?=वह यह है कि ?=शामिल नहीं पूरे मैच से अभिव्यक्ति, जबकि ?:सिर्फ एक कैप्चरिंग समूह नहीं बनाया है। इसलिए उदाहरण के लिए a(?:b)"abc" में "ab" का a(?=b)मिलान होगा , जबकि केवल "abc" में "a" का मिलान होगा। a(b)"abc" में "ab" से मेल खाएगा और "b" युक्त कैप्चर बनाएगा।


78
?:  is for non capturing group
?=  is for positive look ahead
?!  is for negative look ahead
?<= is for positive look behind
?<! is for negative look behind

कृपया यहां देखें: नियमित अभिव्यक्तियों में बहुत अच्छे ट्यूटोरियल और उदाहरणों के लिए http : //www . अनियमित-expressions.info/lookaround.html।


15
फिर भी जावास्क्रिप्ट लुकबाइंड को नहीं जानता है।
बरगी

1
यह सामान्य रेगेक्स के लिए अधिक पूर्ण है।
यान यांग

/ (? <= ^ a) b / मेरे लिए जावास्क्रिप्ट में काम किया! लगता है कि इंटरनेट पर जावास्क्रिप्ट में पीछे देखने के लिए कोई ट्यूटोरियल नहीं है।
वाई। योशी

केवल हालिया संस्करणों के ब्राउज़रों ने JS में समर्थन देखना शुरू कर दिया है
anubhava

- शुभाशुभ मुझे शुद्ध नियमित अभिव्यक्ति के लिए / (? <= ^ A) b / का कोई विकल्प नहीं पता है। शायद मैं कर सकता हूं, लेकिन मुझे कॉलबैक फ़ंक्शन पर भरोसा करना होगा।
वाई। योशी

21

बेहतर समझने के लिए आइए तीन अभिव्यक्तियों और एक कैप्चरिंग समूह को लागू करें और प्रत्येक व्यवहार का विश्लेषण करें।

  • () कैप्चरिंग ग्रुप - कोष्ठक के अंदर रेगेक्स का मिलान किया जाना चाहिए और मैच कैप्चरिंग ग्रुप बना सकता है
  • (?:) गैर कैप्चरिंग समूह - कोष्ठक के अंदर रेगेक्स का मिलान किया जाना चाहिए, लेकिन कैप्चरिंग समूह नहीं बनाता है
  • (?=) सकारात्मक देखो आगे - जोर देता है कि regex का मिलान किया जाना चाहिए
  • (?!) नेगेटिव लुक आगे - यह दावा करता है कि regex का मिलान करना असंभव है

चलो छोड़ो आवेदन q(u)iकरते हैं । मैच क्यू और कैप्चरिंग ग्रुप मैच यू । कैप्चरिंग ग्रुप के अंदर मैच लिया जाता है और कैप्चरिंग ग्रुप बनाया जाता है। तो इंजन के साथ जारी है । और पूर्ति करेंगे, मैं । मैच का यह आखिरी प्रयास सफल है। क्यू मिलान किया गया है और यू के साथ एक कैप्चरिंग ग्रुप हैquii बनाया जाता है।

चलो छोड़ो आवेदन q(?:u)iकरते हैं । फिर, मैच q और गैर-कैप्चरिंग ग्रुप मैच मैच यू । गैर-कैप्चरिंग ग्रुप से मैच लिया जाता है, लेकिन कैप्चरिंग ग्रुप नहीं बनाया जाता है। तो इंजन के साथ जारी है । और पूर्ति करेंगे, मैं । मैच का यह आखिरी प्रयास सफल है। क्वि का मिलान किया जाता हैquii

चलो छोड़ो आवेदन q(?=u)iकरते हैं । लुकहेड सकारात्मक है और इसके बाद एक और टोकन है। फिर, मेल खाता क्ष और मैचों यू । फिर से, लुकहेड से मैच को छोड़ दिया जाना चाहिए, इसलिए इंजन स्ट्रिंग से यू में वापस कदम रखता है । लुकहेड सफल था, इसलिए इंजन के साथ जारी है । लेकिन मेल नहीं खा सकता यू । इसलिए यह मैच का प्रयास विफल हो जाता है।quiii

चलो छोड़ो आवेदन q(?=u)uकरते हैं । लुकहेड सकारात्मक है और इसके बाद एक और टोकन है। फिर, मेल खाता क्ष और मैचों यू । लुकहेड से मैच को छोड़ दिया जाना चाहिए, इसलिए इंजन स्ट्रिंग से यू में वापस कदम रखता है । लुकहेड सफल था, इसलिए इंजन के साथ जारी है । और यू से मेल खाएगा । इसलिए मैच का यह प्रयास सफल है। ququuuu का मिलान किया जाता है

चलो छोड़ो आवेदन q(?!i)uकरते हैं । यहां तक ​​कि इस मामले में लुकहेड सकारात्मक है (क्योंकि मेल नहीं खाता) और इसके बाद एक और टोकन है। फिर से q से मेल खाता है और यू से मेल नहीं खाता है । लुकहेड से मैच को छोड़ दिया जाना चाहिए, इसलिए इंजन स्ट्रिंग से यू में वापस कदम रखता है । लुकहेड सफल था, इसलिए इंजन के साथ जारी है । और यू से मेल खाएगा । इसलिए मैच का यह प्रयास सफल है। quiqiuuu का मिलान किया जाता है

इसलिए, निष्कर्ष में, लुकहेड और गैर-कैप्चरिंग समूहों के बीच वास्तविक अंतर यह है कि क्या आप सिर्फ अस्तित्व या परीक्षण का परीक्षण करना चाहते हैं और मैच को बचा सकते हैं। कैप्चरिंग ग्रुप महंगे हैं इसलिए इसका इस्तेमाल विवेकपूर्ण तरीके से करें।


> तो इंजन स्ट्रिंग में i से i तक वापस कदम रखता है। लुकहेड सफल था, इसलिए इंजन i के साथ जारी है। लेकिन मैं यू मिलान नहीं कर सकता पूरी तरह से भ्रमित है। अगर यह लुकहेड है तो कदम पीछे क्यों ?
ग्रीन

1
@Green लाहेहेड और अन्य दिखावट निर्माणों के बारे में समझने के लिए एक महत्वपूर्ण बात यह है कि यद्यपि वे गतियों के माध्यम से जाते हैं यह देखने के लिए कि क्या उनका सब-डेप्रिसिएशन मेल करने में सक्षम है, वे वास्तव में किसी पाठ का "उपभोग" नहीं करते हैं। यह थोड़ा भ्रमित करने वाला हो सकता है
स्वतंत्रता दिवस

7

foobarइनके विरुद्ध मिलान का प्रयास करें :

/foo(?=b)(.*)/
/foo(?!b)(.*)/

पहला रेगेक्स मैच करेगा और "बार" को पहले सबमैच के रूप में लौटाएगा - (?=b)'बी' से मेल खाता है, लेकिन इसका उपभोग नहीं करता है, इसे निम्न कोष्ठक के लिए छोड़ देता है।

दूसरा रेगेक्स मेल नहीं खाएगा, क्योंकि यह उम्मीद करता है कि "फू" का 'बी' से कुछ अलग होगा।

(?:...)बिल्कुल सरल के रूप में एक ही प्रभाव है (...), लेकिन यह एक अंश के रूप में उस हिस्से वापस नहीं करता है।


0

मुखरता को समझने का सबसे सरल तरीका उन्हें एक नियमित अभिव्यक्ति में सम्मिलित कमांड के रूप में माना जाता है। जब इंजन एक जोर के लिए चलता है, तो यह तुरंत दावे द्वारा वर्णित स्थिति की जांच करेगा। यदि परिणाम सही है, तो नियमित अभिव्यक्ति को चलाना जारी रखें।


0

यही वास्तविक अंतर है:

>>> re.match('a(?=b)bc', 'abc')
<Match...>
>>> re.match('a(?:b)c', 'abc')
<Match...>

# note:
>>> re.match('a(?=b)c', 'abc')
None

यदि आप "?:" या "? =", "?:" और "? =" के बाद सामग्री की देखभाल नहीं करते हैं, तो केवल एक ही हैं। दोनों का उपयोग करना ठीक है।

लेकिन अगर आपको आगे की प्रक्रिया के लिए उन सामग्री की आवश्यकता है (न कि पूरी बात से मेल खाए। उस स्थिति में आप बस "a? B" का उपयोग कर सकते हैं) इसके बजाय आपको "? =" का उपयोग करना होगा। कारण "?:" बस इसके माध्यम से दूर होगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.