Regular Expressions
लालची और आलसी क्वांटिफायर
खोज…
पैरामीटर
परिमाणकों | विवरण |
---|---|
? | पूर्ववर्ती चरित्र या उपप्रकार 0 या 1 बार (अधिमानतः 1) का मिलान करें। |
* | पूर्ववर्ती चरित्र या उपप्रकार से 0 या अधिक बार (जितना संभव हो) मिलान करें। |
+ | पूर्ववर्ती चरित्र या उपप्रकार 1 या अधिक बार (जितना संभव हो उतना) मिलान करें। |
{n} | पूर्ववर्ती वर्ण या उपसर्ग का मिलान बिल्कुल n बार करें। |
{min,} | पूर्ववर्ती चरित्र या उपप्रकार मिनट या अधिक से अधिक बार मेल करें (जितना संभव हो)। |
{0,max} | पूर्ववर्ती चरित्र या उपप्रकार के अधिकतम या कम समय (जितना संभव हो अधिकतम के करीब) से मिलान करें। |
{min,max} | पूर्ववर्ती चरित्र या उपप्रकार से कम से कम न्यूनतम बार मिलान करें लेकिन अधिकतम समय (जितना संभव हो अधिकतम के करीब) से अधिक नहीं। |
आलसी क्वांटिफायर | विवरण |
?? | पूर्ववर्ती वर्ण या उपप्रकार से 0 या 1 बार मेल करें (अधिमानतः 0)। |
*? | पूर्ववर्ती वर्ण या उपप्रकार 0 या अधिक बार (जितना संभव हो कम) मेल करें। |
+? | पूर्ववर्ती चरित्र या उपप्रकार 1 या अधिक बार (जितना संभव हो उतना कम) मिलान करें। |
{n}? | पूर्ववर्ती वर्ण या उपसर्ग का मिलान बिल्कुल n बार करें। लालची और आलसी संस्करण के बीच कोई अंतर नहीं है। |
{min,}? | पूर्ववर्ती चरित्र या उपप्रकार मिनट या अधिक से अधिक बार मेल करें (जितना संभव हो उतना न्यूनतम मिनट )। |
{0,max}? | पूर्ववर्ती चरित्र या उपप्रकार का अधिकतम या कम समय (जितना संभव हो कम) से मिलान करें। |
{min,max}? | पूर्ववर्ती चरित्र या उपप्रकार से कम से कम न्यूनतम बार मिलान करें लेकिन अधिकतम समय से अधिक नहीं (जितना संभव हो उतना न्यूनतम मिनट )। |
टिप्पणियों
लालच
एक लालची क्वांटिफायर हमेशा बैकट्रैकिंग द्वारा छोटे मैचों की खोज करने से पहले कई बार उप-पैटर्न को दोहराने का प्रयास करता है।
आम तौर पर, एक लालची पैटर्न सबसे लंबे समय तक संभव स्ट्रिंग से मेल खाएगा।
डिफ़ॉल्ट रूप से, सभी क्वांटिफायर लालची होते हैं।
आलस्य
एक आलसी (भी गैर लालची या अनिच्छुक कहा जाता है) परिमाणक हमेशा प्रयास संभव के रूप में कई बार के रूप में उप पैटर्न दोहराने के लिए, विस्तार से लंबे समय तक मैचों की खोज से पहले।
आम तौर पर, एक आलसी पैटर्न सबसे कम संभव स्ट्रिंग से मेल खाएगा।
क्वांटिफ़ायर को आलसी बनाने के लिए, बस अपेंड करें ?
मौजूदा क्वांटिफायर के लिए, जैसे +?
, {0,5}?
।
लालच और आलस्य की अवधारणा केवल बैकट्रैकिंग इंजन में मौजूद है
लालची / आलसी क्वांटिफायर की धारणा केवल रेगीक्स इंजनों में ही मौजूद है। नॉन-बैकट्रैकिंग रेगेक्स इंजन या पोसिक्स-कंप्लीट रेगेक्स इंजन में, क्वांटिफायर केवल दोहराव के ऊपरी बाउंड और लोअर बाउंड को निर्दिष्ट करते हैं, बिना यह बताए कि मैच कैसे खोजें - उन इंजन हमेशा परवाह किए बिना बाएं-सबसे लंबे स्ट्रिंग से मेल खाएंगे।
लालच बनाम आलस्य
निम्नलिखित इनपुट को देखते हुए:
aaaaaAlazyZgreeedyAlaaazyZaaaaa
हम दो पैटर्न का उपयोग करेंगे: एक लालची: A.*Z
, और एक आलसी: A.*?Z
। ये पैटर्न निम्नलिखित मैचों की उपज देते हैं:
-
A.*Z
पैदावार 1 मैच:AlazyZgreeedyAlaaazyZ
(उदाहरण: Regex101 , Rubular ) -
A.*?Z
पैदावार 2 मैच:AlazyZ
औरAlaaazyZ
(उदाहरण: Regex101 , Rubular )
पहले ध्यान केंद्रित करें कि A.*Z
क्या करता है। जब यह पहले A
, .*
से मेल खाता था, लालची हो रहा था, तो बहुत से मिलान करने की कोशिश करता है .
यथासंभव।
aaaaaAlazyZgreeedyAlaaazyZaaaaa
\________________________/
A.* matched, Z can't match
चूंकि Z
मेल नहीं खाता है, इंजन पीछे हटता है, और .*
फिर एक कम मेल खाना चाहिए .
:
aaaaaAlazyZgreeedyAlaaazyZaaaaa
\_______________________/
A.* matched, Z can't match
यह कुछ और समय तक होता है, जब तक कि अंत में यह नहीं आता है:
aaaaaAlazyZgreeedyAlaaazyZaaaaa
\__________________/
A.* matched, Z can now match
अब Z
मिलान कर सकता है, इसलिए समग्र पैटर्न मेल खाता है:
aaaaaAlazyZgreeedyAlaaazyZaaaaa
\___________________/
A.*Z matched
इसके विपरीत, A.*?Z
में अनिच्छुक (आलसी) पुनरावृत्ति A.*?Z
पहले कुछ के रूप में मेल खाता है .
जितना संभव हो, और फिर अधिक लेना .
यथावश्यक। यह बताता है कि यह इनपुट में दो मैच क्यों ढूंढता है।
यहाँ दो पैटर्न से मिलान का एक दृश्य प्रतिनिधित्व है:
aaaaaAlazyZgreeedyAlaaazyZaaaaa
\____/l \______/l l = lazy
\_________g_________/ g = greedy
पॉलीजेनबेलिकेंट द्वारा किए गए उत्तर के आधार पर उदाहरण।
POSIX मानक में शामिल नहीं है ?
ऑपरेटर, इतने सारे POSIX regex इंजन में आलसी मिलान नहीं है । रिफैक्टिंग करते समय, विशेष रूप से "सबसे बड़ी चाल" के साथ , कुछ मामलों में मैच में मदद मिल सकती है, सही आलसी मिलान का एकमात्र तरीका एक इंजन का उपयोग करना है जो इसका समर्थन करता है।
कई मैचों के साथ सीमा
जब आपके पास अच्छी तरह से परिभाषित सीमाओं के साथ एक इनपुट होता है और आपकी स्ट्रिंग में एक से अधिक मैच होने की उम्मीद होती है, तो आपके पास दो विकल्प होते हैं:
- आलसी क्वांटिफायर का उपयोग करना;
- एक उपेक्षित चरित्र वर्ग का उपयोग करना।
निम्नलिखित को धयान मे रखते हुए:
आपके पास एक सरल टेंपलेटिंग इंजन है, आप सब्सट्रिंग को $[foo]
तरह बदलना चाहते हैं जहां foo
किसी भी स्ट्रिंग हो सकता है। आप इस सबस्ट्रिंग को []
बीच के हिस्से के आधार पर प्रतिस्थापित करना चाहते हैं।
आप \$\[(.*)\]
जैसी कुछ कोशिश कर सकते हैं, और फिर पहले कैप्चर समूह का उपयोग कर सकते हैं।
इसके साथ समस्या यह है कि यदि आपके पास कुछ स्ट्रिंग है जैसे something $[foo] lalala $[bar] something else
आपका मैच something $[foo] lalala $[bar] something else
होगा
something $[foo] lalala $[bar] something else
| \______CG1______/|
\_______Match______/
कब्जा समूह foo] lalala $[bar
जो मान्य हो सकता है या नहीं हो सकता है।
आपके पास दो उपाय हैं
आलस्य का उपयोग करना: इस मामले में
*
आलसी बनाना सही चीजों को खोजने का एक तरीका है। इसलिए आप अपनी अभिव्यक्ति को\$\[(.*?)\]
उपेक्षित चरित्र वर्ग का उपयोग करते हुए:
[^\]]
आप अपनी अभिव्यक्ति को बदलकर\$\[([^\]]*)\]
।
दोनों समाधानों में, परिणाम समान होगा:
something $[foo] lalala $[bar] something else
| \_/| | \_/|
\____/ \____/
कब्जा समूह क्रमशः foo
और bar
।
नेगेटिव कैरेक्टर क्लास का इस्तेमाल करने से बैकट्रैकिंग की समस्या कम हो जाती है और बड़े इनपुट की बात आने पर आपके सीपीयू को काफी समय बच सकता है।