2009-07-16 22 views
22

Pattern javadocs से:'लालची' और 'अनिच्छुक' नियमित अभिव्यक्ति क्वांटिफायर के बीच क्या अंतर है?

 
Greedy quantifiers: 
X?  X, once or not at all 
X*  X, zero or more times 
X+  X, one or more times 
X{n} X, exactly n times 
X{n,} X, at least n times 
X{n,m} X, at least n but not more than m times 

Reluctant quantifiers: 
X??  X, once or not at all 
X*?  X, zero or more times 
X+?  X, one or more times 
X{n}? X, exactly n times 
X{n,}? X, at least n times 
X{n,m}? X, at least n but not more than m times 

वे क्या करते हैं एक ही है ... इसलिए, क्या अंतर है है का वर्णन?

मैं वास्तव में कुछ उदाहरणों की सराहना करता हूं।

मैं जावा में कोडिंग कर रहा हूं, लेकिन मुझे लगता है कि यह अवधारणा अधिकांश आधुनिक रेगेक्स कार्यान्वयन के लिए समान है।

+2

मुझे स्टैक ओवरफ्लो पसंद है। 15 मिनट से कम समय में इस तरह के महान जवाब। – jjnguy

+1

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

+0

आह, जानना दिलचस्प है। – jjnguy

उत्तर

36

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

उदाहरण:

"The red fox jumped over the red fence" 
/(.*)red/ => \1 = "The red fox jumped over the " 
/(.*?)red/ => \1 = "The " 

"aaa" 
/a?a*/ => \1 = "a", \2 = "aa" 
/a??a*/ => \1 = "", \2 = "aaa" 

"Mr. Doe, John" 
/^(?:Mrs?.)?.*\b(.*)$/ => \1 = "John" 
/^(?:Mrs?.)?.*?\b(.*)$/ => \1 = "Doe, John" 
+0

यह वास्तव में एक अच्छा उदाहरण है। – Salty

3

एक लालची क्वांटिफायर जितना संभव हो सके मैच करेगा और अभी भी एक मैच प्राप्त होगा एक अनिच्छुक क्वांटिफायर संभवतः सबसे छोटी राशि से मेल खाता है।

उदाहरण के लिए

स्ट्रिंग

लालची क्वालीफायर

अब [az] * [az] abcdef

अनिच्छुक क्वालीफायर

अब से मेल खाएंगे [az abcdef दिया ] *? [एजे] एबीसी

+0

असल में, लालची चरित्र वर्ग "सीडीई" से मेल खाएगा , चूंकि एक मैच एक मैच करेगा, बी बी से मेल खाएगा और आखिरी [एजे] एफ से मेल खाएगा। अनिच्छुक चरित्र समूह ठीक उसी बात से मेल खाता है – PatrikAkerstrand

+1

@ माचिन: ​​आप गलत हैं, [ए-जेड] *? [ए-जेड] _always_ _first_ [a-z] चरित्र से मेल खाता है! 1. [ए-जेड] *? पहले अगले नियम पर कूदता है: [ए-जेड], अगर वह मेल नहीं खाता तो [a-z] *? या तो मेल नहीं खाएगा, और यह कहानी का अंत है। लेकिन 2. अगर [ए-जेड] मैचों, सभी खुश हैं ... – Vili

3

कहते हैं कि तुम एक regex "a\w*b" है, और "abab" लालची मिलान पर इसका इस्तेमाल "abab" (यह एक b एक a के लिए लग रहा है \w संभव के रूप में की ज्यादा घटनाओं के रूप में, और) से मेल खाएगी और अनिच्छुक मिलान केवल "ab" (जितना संभव हो उतना \w जितना संभव हो)

9

this link से, जहां ट्यूटोरियल लेखक स्वीकार करता है आपके प्रश्न की भावना:

पहली नज़र में यह दिखाई दे सकता है कि क्वांटिफायर एक्स ?, एक्स ?? और एक्स? + बिल्कुल वही बात है, क्योंकि वे सभी "एक्स, एक बार या नहीं सभी" से मेल करने का वादा करते हैं। सूक्ष्म कार्यान्वयन मतभेद हैं जो इस खंड के अंत के पास समझाए जाएंगे।

लालची परिमाणकों माना जाता है "लालची" क्योंकि वे मिलान के लिए मजबूर में पढ़ा, या खाने के लिए, पूरे इनपुट स्ट्रिंग:

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

अनिच्छुक परिमाणकों, तथापि, विपरीत दृष्टिकोण अपनाते हैं: वे इनपुट स्ट्रिंग की शुरुआत में शुरू करते हैं, तो अनिच्छा से एक चरित्र पर एक समय में एक मैच के लिए देख खाते हैं। अंतिम वे जिस चीज को आजमाते हैं वह संपूर्ण इनपुट स्ट्रिंग है।

और अतिरिक्त क्रेडिट के लिए, अधिकार स्पष्टीकरण:

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

+1

भी इसके बारे में अतिरिक्त जानकारी के लिए धन्यवाद। – jjnguy

2

पेर्ल इन क्वांटिफ़ायर perldoc perlre को कैसे प्रबंधित करता है इस पर प्रलेखन है।

डिफ़ॉल्ट रूप से, एक प्रमाणित उप-पैटर्न "लालची" होता है, यानी, जितना संभव हो सके उतना बार मिलान होगा (एक विशेष प्रारंभिक स्थान दिया जाता है) जबकि बाकी पैटर्न को मिलान करने की अनुमति मिलती है। यदि आप इसे कम से कम कई बार मिलान करना चाहते हैं, तो " ?" के साथ क्वांटिफ़ायर का पालन करें। ध्यान दें कि अर्थ बदलते नहीं हैं, केवल "लालच":
 
    *?  Match 0 or more times, not greedily 
    +?  Match 1 or more times, not greedily 
    ??  Match 0 or 1 time, not greedily 
    {n}? Match exactly n times, not greedily 
    {n,}? Match at least n times, not greedily 
    {n,m}? Match at least n but not more than m times, not greedily 
डिफ़ॉल्ट रूप से, जब एक मात्रात्मक उप-पैटर्न पूरे समग्र पैटर्न को मिलान करने की अनुमति नहीं देता है, तो पर्ल बैकट्रैक होगा। हालांकि, यह व्यवहार कभी-कभी अवांछित होता है। इस प्रकार पर्ल "स्वामित्व" क्वांटिफायर फॉर्म भी प्रदान करता है।
 
    *+  Match 0 or more times and give nothing back 
    ++  Match 1 or more times and give nothing back 
    ?+  Match 0 or 1 time and give nothing back 
    {n}+ Match exactly n times and give nothing back (redundant) 
    {n,}+ Match at least n times and give nothing back 
    {n,m}+ Match at least n but not more than m times and give nothing back 
उदाहरण के लिए ,
 
    'aaaa' =~ /a++a/ 
से मेल खाते हैं कभी नहीं होगा, के रूप में a++ स्ट्रिंग में सभी a के ऊपर हडप जाना होगा और पैटर्न के शेष भाग के लिए किसी भी नहीं छोड़ देंगे। यह सुविधा पेर्ल संकेत देने के लिए बेहद उपयोगी हो सकती है कि इसे पीछे हटाना नहीं चाहिए। उदाहरण के लिए, सामान्य "एक डबल-उद्धृत स्ट्रिंग से मिलान करें" समस्या को सबसे कुशलता से किया जा सकता है जब लिखा गया:
 
    /"(?:[^"\\]++|\\.)*+"/ 
जैसा कि हम जानते हैं कि यदि अंतिम उद्धरण मेल नहीं खाता है, तो बैकट्रैकिंग मदद नहीं करेगा। अधिक जानकारी के लिए स्वतंत्र उप-अभिव्यक्ति (?>...) देखें; स्वामित्व वाले क्वांटिफायर उस निर्माण के लिए सिंटैक्टिक चीनी हैं। उदाहरण के लिए उपर्युक्त उदाहरण भी निम्नानुसार लिखा जा सकता है:
 
    /"(?>(?:(?>[^"\\]+)|\\.)*)"/ 
संबंधित मुद्दे