दोनों के बीच क्या अंतर है ।*? और। * नियमित अभिव्यक्ति?


142

मैं regex का उपयोग करके एक स्ट्रिंग को दो भागों में विभाजित करने की कोशिश कर रहा हूं। स्ट्रिंग निम्नानुसार स्वरूपित है:

text to extract<number>

मैं उपयोग कर रहा हूं (.*?)<और <(.*?)>जो ठीक काम कर रहा है, लेकिन रेगेक्स में थोड़ा पढ़ने के बाद, मुझे आश्चर्यचकित होना शुरू हो गया है कि मुझे ?अभिव्यक्तियों की आवश्यकता क्यों है । मैंने केवल इसे इस तरह किया है कि इस साइट के माध्यम से उन्हें खोजने के बाद मैं बिल्कुल निश्चित नहीं हूं कि अंतर क्या है।


1
यह भी देखें stackoverflow.com/questions/2301285/…
Cemafor

जवाबों:


172

यह लालची और गैर-लालची क्वांटिफायर के बीच का अंतर है।

इनपुट पर विचार करें 101000000000100

उपयोग करना 1.*1, *लालची है - यह अंत तक सभी तरह से मेल खाएगा, और तब तक पीछे हट सकता है जब तक कि यह 1आपके साथ छोड़कर मैच नहीं कर सकता 1010000000001
.*?गैर-लालची है। *कुछ भी मैच नहीं करेगा, लेकिन फिर जब तक यह मेल नहीं खाता 1, तब तक अतिरिक्त पात्रों से मेल खाने की कोशिश करेगा 101

: सभी परिमाणकों एक गैर लालची विधा है .*?, .+?, .{2,6}?, और यहां तक.??

आपके मामले में, एक समान पैटर्न हो सकता है <([^>]*)>- कुछ भी मेल खाता है, लेकिन अधिक से अधिक संकेत (सख्ती से बोलना, यह शून्य या अधिक पात्रों के >बीच <और इसके अलावा >) से मेल खाता है ।

क्वांटिफायर चीट शीट देखें ।


आह महान मैं कुछ भी है कि पिछले एक की तरह> साइन!
डग

1
क्या आप समझा सकते हैं या एक उदाहरण दिखा सकते हैं कि लालची ?गैर-लालची से कैसे भिन्न होता है ???
एड्रियनएचएच

4
ज़रूर। स्ट्रिंग के लिए "abc", रेगेक्स /\w\w?\w/पूर्ण स्ट्रिंग से मेल खाएगा "abc"- क्योंकि ?लालची है। /\w\w??\w/आलसी है - यह केवल मेल खाएगा "ab""abc"यदि यह बाद में विफल हो जाता है तो यह केवल बैकट्रैक और मैच करेगा ।
कोबी

184

लालची बनाम गैर-लालची

डिफ़ॉल्ट रूप से रेगेक्स में पुनरावृत्ति लालची है : वे अधिक से अधिक प्रतिनिधि मैच करने की कोशिश करते हैं, और जब यह काम नहीं करता है और उन्हें पीछे हटना पड़ता है, तो वे एक बार में एक कम प्रतिनिधि से मेल खाने की कोशिश करते हैं, जब तक कि पूरे पैटर्न का एक मैच नहीं होता है। मिल गया। नतीजतन, जब एक मैच अंत में होता है, एक लालची दोहराव के रूप में कई मैच होगा प्रतिनिधि के रूप में संभव है।

?पुनरावृत्ति परिमाणक में इस व्यवहार में परिवर्तन के रूप में गैर लालची भी कहा जाता है अनिच्छुक ( जैसे जावा में ) (और कभी कभी "आलसी")। इसके विपरीत, यह पुनरावृत्ति सबसे पहले संभव के रूप में कुछ प्रतिनिधि से मेल खाने की कोशिश करेगा , और जब यह काम नहीं करता है और उन्हें पीछे हटना पड़ता है, तो वे एक बार फिर से एक और मिलान शुरू करते हैं। नतीजतन, जब एक मैच अंत में होता है, तो एक अनिच्छुक पुनरावृत्ति संभव के रूप में कुछ प्रतिनिधि से मेल खाती है।

संदर्भ


उदाहरण 1: A से Z तक

आइए इन दो पैटर्नों की तुलना करें: A.*Zऔर A.*?Z

निम्नलिखित इनपुट को देखते हुए:

eeeAiiZuuuuAoooZeeee

पैटर्न निम्नलिखित मैचों का उत्पादन करते हैं:

आइए पहले ध्यान दें कि क्या A.*Zकरता है। जब यह पहले से मेल खाता था A, तो .*लालची होने के नाते, पहले .जितना संभव हो उतना मिलान करने की कोशिश करता है।

eeeAiiZuuuuAoooZeeee
   \_______________/
    A.* matched, Z can't match

चूंकि Zमेल नहीं खाता है, इंजन पीछे हटता है, और .*फिर एक कम से मेल खाना चाहिए .:

eeeAiiZuuuuAoooZeeee
   \______________/
    A.* matched, Z still can't match

यह कुछ और बार होता है, जब तक कि आखिरकार हम इस पर नहीं आते:

eeeAiiZuuuuAoooZeeee
   \__________/
    A.* matched, Z can now match

अब Zमिलान कर सकते हैं, इसलिए समग्र पैटर्न मेल खाता है:

eeeAiiZuuuuAoooZeeee
   \___________/
    A.*Z matched

इसके विपरीत, A.*?Zपहले मैच में अनिच्छुक पुनरावृत्ति .संभव के रूप में कुछ के रूप में, और फिर .आवश्यक के रूप में अधिक ले रहा है। यह बताता है कि यह इनपुट में दो मैच क्यों ढूंढता है।

यहाँ दो पैटर्न क्या मिला का एक दृश्य प्रतिनिधित्व है:

eeeAiiZuuuuAoooZeeee
   \__/r   \___/r      r = reluctant
    \____g____/        g = greedy

उदाहरण: एक विकल्प

कई अनुप्रयोगों में, उपरोक्त इनपुट में दो मैच वांछित है, इस प्रकार अतिरेक को रोकने .*?के लिए लालची के बजाय अनिच्छुक उपयोग किया जाता है .*। इस विशेष पैटर्न के लिए, हालांकि, नकारात्मक चरित्र वर्ग का उपयोग करते हुए एक बेहतर विकल्प है।

पैटर्न A[^Z]*Zभी A.*?Zउपरोक्त इनपुट के लिए पैटर्न के रूप में एक ही दो मैच पाता है ( जैसा कि ideone.com पर देखा गया है )। [^Z]जिसे एक नकारात्मक चरित्र वर्ग कहा जाता है : यह किसी भी चीज़ से मेल खाता है लेकिनZ

दो पैटर्न के बीच मुख्य अंतर प्रदर्शन में है: अधिक सख्त होने के नाते, नकारात्मक चरित्र वर्ग केवल दिए गए इनपुट के लिए एक ही तरीके से मेल खा सकता है। इससे कोई फर्क नहीं पड़ता कि आप इस पैटर्न के लिए लालची या अनिच्छुक संशोधक का उपयोग करते हैं। वास्तव में, कुछ स्वादों में, आप और भी बेहतर कर सकते हैं और उपयोग किया जा सकता है, जिसे अधिकारपूर्ण क्वांटिफायर कहा जाता है, जो बिल्कुल भी पीछे नहीं हटता है।

संदर्भ


उदाहरण 2: A से ZZ तक

यह उदाहरण चित्रमय होना चाहिए: यह दिखाता है कि लालची, अनिच्छुक और नकारा चरित्र वर्ग पैटर्न एक ही इनपुट को अलग तरह से कैसे मेल खाते हैं।

eeAiiZooAuuZZeeeZZfff

उपरोक्त इनपुट के लिए ये मैच हैं:

यहाँ वे क्या मिलान का एक दृश्य प्रतिनिधित्व है:

         ___n
        /   \              n = negated character class
eeAiiZooAuuZZeeeZZfff      r = reluctant
  \_________/r   /         g = greedy
   \____________/g

संबंधित विषय

ये स्टैकओवरफ्लो पर सवाल और जवाब के लिंक हैं जो कुछ विषयों को कवर करते हैं जो रुचि के हो सकते हैं।

एक लालची पुनरावृत्ति दूसरे से आगे निकल सकती है


1
मेरा कहने का मतलब था rubular.com, ideone.com नहीं। दूसरों के लिए: मेरे लिए इस पोस्ट को संशोधित न करें, मैं इसे अगले संशोधन पर स्वयं करूंगा, अन्य उदाहरणों के साथ। टिप्पणियों में प्रतिक्रिया, सुझाव, आदि देने के लिए स्वतंत्र महसूस करें ताकि मैं उन्हें भी शामिल कर सकूं।
पॉलीजेन लुब्रीकेंट



यह उत्तर वास्तव में चुने हुए उत्तर के योग्य है!। आपके विस्तृत विवरण के लिए बहुत बहुत धन्यवाद।
मास्क 0000 7

मैंने गैर-लालची टैग जोड़ा । क्यों, क्योंकि प्रश्न की आवश्यकता थी, लेकिन यह भी क्योंकि यह इस महान उत्तर के लिए अधिक उपयोगकर्ताओं को फ़नल करेगा। दूसरे शब्दों में, यदि आप एक शानदार उत्तर देते हैं और उत्तर प्रश्न में नहीं टैग का उपयोग करता है, तो टैग जोड़ें क्योंकि ओपी को पता नहीं था कि टैग प्रचलित था।
गाय कोडर

20

मान लीजिए कि आपके पास है:

<a></a>

<(.*)>a></aजहां मैच होगा वहीं मैच <(.*?)>होगा a। के पहले मैच के बाद उत्तरार्द्ध बंद हो जाता है >। यह .*अगले अभिव्यक्ति के बाद एक या 0 मैचों के लिए जाँच करता है ।

पहले से <(.*)>मेल खाते समय पहली अभिव्यक्ति बंद नहीं होती है >। यह आखिरी मैच तक जारी रहेगा >


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