regex - एक गैर कैप्चरिंग समूह क्या है? क्या करता है?




capturing-group regex-group (8)

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

मान लें कि आप संख्यात्मक पाठ से मेल खाना चाहते हैं, लेकिन कुछ संख्याओं को 1, 2, 3, 4 वें, के रूप में लिखा जा सकता है ... यदि आप संख्यात्मक भाग को कैप्चर करना चाहते हैं, लेकिन (वैकल्पिक) प्रत्यय नहीं है तो आप एक गैर-कैप्चरिंग समूह का उपयोग कर सकते हैं ।

([0-9]+)(?:st|nd|rd|th)?

वह फॉर्म 1, 2, 3 ... या फॉर्म 1, 2, 3, में संख्या से मेल खाता है ... लेकिन यह केवल संख्यात्मक भाग को कैप्चर करेगा।

कैसे ?: प्रयोग किया जाता है और यह किसके लिए अच्छा है?


एक दिलचस्प बात जो मैंने पार की थी वह यह तथ्य है कि आप एक गैर-कैप्चरिंग समूह के अंदर कैप्चरिंग समूह कर सकते हैं। वेब यूआरएल से मेल खाने के लिए नीचे रेगेक्स पर एक नज़र डालें:

var parse_url_regex = /^(?:([A-Za-z]+):)(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/;

इनपुट यूआरएल स्ट्रिंग:

var url = "http://www.ora.com:80/goodparts?q#fragment";

मेरे रेगेक्स में पहला समूह (?:([A-Za-z]+):) एक गैर-कैप्चरिंग समूह है जो प्रोटोकॉल योजना और कोलन से मेल खाता है : चरित्र यानी http: लेकिन जब मैं कोड के नीचे चल रहा था, तो मैं देख रहा था लौटा सरणी की पहली अनुक्रमणिका स्ट्रिंग http थी जिसमें मैं सोच रहा था कि http और colon : दोनों को गैर-कैप्चरिंग समूह के अंदर रिपोर्ट नहीं की जाएगी।

console.debug(parse_url_regex.exec(url));

मैंने सोचा कि अगर पहला समूह (?:([A-Za-z]+):) एक गैर-कैप्चरिंग समूह है तो यह आउटपुट सरणी में http स्ट्रिंग क्यों लौटा रहा है।

तो यदि आप ध्यान दें कि गैर-कैप्चरिंग समूह के अंदर एक नेस्टेड समूह ([A-Za-z]+) है। वह नेस्टेड समूह ([A-Za-z]+) एक कैप्चरिंग समूह है (शुरुआत में नहीं ?: शुरुआत में) एक गैर-कैप्चरिंग समूह (?:([A-Za-z]+):) अंदर स्वयं में। यही कारण है कि पाठ http अभी भी कब्जा कर लिया गया है लेकिन कोलन : चरित्र जो गैर-कैप्चरिंग समूह के अंदर है लेकिन कैप्चरिंग समूह के बाहर आउटपुट सरणी में रिपोर्ट नहीं की जाती है।


खैर मैं एक जावास्क्रिप्ट डेवलपर हूं और जावास्क्रिप्ट से संबंधित इसके महत्व को समझाने की कोशिश करूंगा।

एक परिदृश्य पर विचार करें जहां आप cat is animal से मेल खाना चाहते हैं cat is animal जब आप बिल्ली और जानवर से मेल खाते हैं और दोनों के बीच में होना चाहिए।

 // this will ignore "is" as that's is what we want
"cat is animal".match(/(cat)(?: is )(animal)/) ;
result ["cat is animal", "cat", "animal"]

 // using lookahead pattern it will match only "cat" we can
 // use lookahead but the problem is we can not give anything
 // at the back of lookahead pattern
"cat is animal".match(/cat(?= is animal)/) ;
result ["cat"]

 //so I gave another grouping parenthesis for animal
 // in lookahead pattern to match animal as well
"cat is animal".match(/(cat)(?= is (animal))/) ;
result ["cat", "cat", "animal"]

 // we got extra cat in above example so removing another grouping
"cat is animal".match(/cat(?= is (animal))/) ;
result ["cat", "animal"]

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


मुझे उदाहरण के साथ इसे समझाने की कोशिश करें।

निम्नलिखित पाठ पर विचार करें:

https://.com/
https://.com/questions/tagged/regex

अब, अगर मैं इसके ऊपर रेगेक्स लागू करता हूं ...

(https?|ftp)://([^/\r\n]+)(/[^\r\n]*)?

... मुझे निम्नलिखित परिणाम मिलेंगे:

Match "https://.com/"
     Group 1: "http"
     Group 2: ".com"
     Group 3: "/"

Match "https://.com/questions/tagged/regex"
     Group 1: "http"
     Group 2: ".com"
     Group 3: "/questions/tagged/regex"

लेकिन मुझे प्रोटोकॉल की परवाह नहीं है - मैं सिर्फ यूआरएल के मेजबान और पथ चाहता हूं। इसलिए, मैं गैर-कैप्चरिंग समूह (?:) को शामिल करने के लिए रेगेक्स को बदलता हूं।

(?:https?|ftp)://([^/\r\n]+)(/[^\r\n]*)?

अब, मेरा परिणाम इस तरह दिखता है:

Match "https://.com/"
     Group 1: ".com"
     Group 2: "/"

Match "https://.com/questions/tagged/regex"
     Group 1: ".com"
     Group 2: "/questions/tagged/regex"

देख? पहला समूह कब्जा नहीं किया गया है। पार्सर पाठ से मेल खाने के लिए इसका उपयोग करता है, लेकिन अंतिम परिणाम में बाद में इसे अनदेखा करता है।

संपादित करें:

अनुरोध के रूप में, मुझे समूहों को भी समझाने की कोशिश करें।

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

ठीक है, कल्पना करें कि आपके पास कुछ प्रकार का एक्सएमएल या एचटीएमएल है (जागरूक रहें कि नौकरी नौकरी के लिए सबसे अच्छा उपकरण नहीं हो सकता है , लेकिन यह एक उदाहरण के रूप में अच्छा है)। आप टैग को पार्स करना चाहते हैं, इसलिए आप ऐसा कुछ कर सकते हैं (मैंने समझने में आसान बनाने के लिए रिक्त स्थान जोड़े हैं):

   \<(?<TAG>.+?)\> [^<]*? \</\k<TAG>\>
or
   \<(.+?)\> [^<]*? \</\1\>

पहले रेगेक्स में एक नामित समूह (TAG) है, जबकि दूसरा एक आम समूह का उपयोग करता है। दोनों regexes एक ही काम करते हैं: वे बंद टैग से मेल खाने के लिए पहले समूह (टैग का नाम) से मूल्य का उपयोग करें। अंतर यह है कि पहला व्यक्ति मान से मेल खाने के लिए नाम का उपयोग करता है, और दूसरा समूह समूह का उपयोग करता है (जो 1 से शुरू होता है)।

आइए अब कुछ प्रतिस्थापन आज़माएं। निम्नलिखित पाठ पर विचार करें:

Lorem ipsum dolor sit amet consectetuer feugiat fames malesuada pretium egestas.

अब, इस पर इस गूंगा रेगेक्स का उपयोग करें:

\b(\S)(\S)(\S)(\S*)\b

यह रेगेक्स कम से कम 3 अक्षरों वाले शब्दों से मेल खाता है, और पहले तीन अक्षरों को अलग करने के लिए समूहों का उपयोग करता है। नतीजा यह है:

Match "Lorem"
     Group 1: "L"
     Group 2: "o"
     Group 3: "r"
     Group 4: "em"
Match "ipsum"
     Group 1: "i"
     Group 2: "p"
     Group 3: "s"
     Group 4: "um"
...

Match "consectetuer"
     Group 1: "c"
     Group 2: "o"
     Group 3: "n"
     Group 4: "sectetuer"
...

तो, अगर हम प्रतिस्थापन स्ट्रिंग लागू करते हैं ...

$1_$3$2_$4

... इसके ऊपर, हम पहले समूह का उपयोग करने की कोशिश कर रहे हैं, अंडरस्कोर जोड़ें, तीसरे समूह का उपयोग करें, फिर दूसरा समूह, एक और अंडरस्कोर जोड़ें, और फिर चौथा समूह। परिणामी स्ट्रिंग नीचे दिए गए की तरह होगी।

L_ro_em i_sp_um d_lo_or s_ti_ a_em_t c_no_sectetuer f_ue_giat f_ma_es m_la_esuada p_er_tium e_eg_stas.

आप ${name} का उपयोग करके प्रतिस्थापित समूहों के लिए नामित समूहों का भी उपयोग कर सकते हैं।

रेगेक्स के साथ खेलने के लिए, मैं http://regex101.com/ की अनुशंसा करता हूं, जो रेगेक्स कैसे काम करता है इस बारे में अच्छी जानकारी प्रदान करता है; यह चुनने के लिए कुछ रेगेक्स इंजन भी प्रदान करता है।


मुझे लगता है कि मैं आपको जवाब दूंगा, मैच की सफलता के बिना कैप्चर चर का उपयोग न करें।

कैप्चर वैरिएबल, $ 1, इत्यादि वैध नहीं हैं जब तक कि मैच सफल नहीं हुआ, और वे साफ़ नहीं किए जाते हैं।

#!/usr/bin/perl  
use warnings;
use strict;   
$_ = "bronto saurus burger";
if (/(?:bronto)? saurus (steak|burger)/)
{
    print "Fred wants a  $1";
}
else
{
    print "Fred dont wants a $1 $2";
}

उपर्युक्त उदाहरण में, $ 1 में ब्रोंटो को कैप्चर करने से बचने के लिए, (? :) का उपयोग किया जाता है। यदि पैटर्न मिलान किया गया है, तो $ 1 को अगले समूह पैटर्न के रूप में कैप्चर किया जाता है। तो, आउटपुट नीचे जैसा होगा:

Fred wants a burger

यदि आप नहीं चाहते हैं कि मैचों को सेव किया जाए तो यह उपयोगी है।


यह समूह को गैर-कैप्चरिंग बनाता है, जिसका अर्थ है कि उस समूह द्वारा मिलान किया गया सबस्ट्रिंग कैप्चर की सूची में शामिल नहीं किया जाएगा। अंतर को चित्रित करने के लिए रूबी में एक उदाहरण:

"abc".match(/(.)(.)./).captures #=> ["a","b"]
"abc".match(/(?:.)(.)./).captures #=> ["b"]

समूह जो आपको कैप्चर करते हैं, बाद में रेगेक्स में मिलान करने के लिए उपयोग कर सकते हैं या आप रेगेक्स के प्रतिस्थापन भाग में उनका उपयोग कर सकते हैं। एक गैर-कैप्चरिंग समूह बनाना, इस समूह को इन कारणों में से किसी एक के लिए उपयोग करने से छूट देता है।

गैर-कैप्चरिंग समूह बहुत अच्छे हैं यदि आप कई अलग-अलग चीजों को पकड़ने की कोशिश कर रहे हैं और ऐसे कुछ समूह हैं जिन्हें आप कैप्चर नहीं करना चाहते हैं।

उनके अस्तित्व के कारण बहुत अधिक है। जबकि आप समूहों के बारे में सीख रहे हैं, परमाणु समूहों के बारे में जानें, वे बहुत कुछ करते हैं! यहां तक ​​कि लुकराउंड समूह भी हैं लेकिन वे थोड़ा अधिक जटिल हैं और इनका उपयोग नहीं किया जाता है।

बाद में रेगेक्स (बैकरेफर) में उपयोग करने का उदाहरण:

<([AZ][A-Z0-9]*)\b[^>]*>.*?</\1> [एक एक्सएमएल टैग ढूंढता है (एनएस समर्थन के बिना)]

([AZ][A-Z0-9]*) एक कैप्चरिंग समूह है (इस मामले में यह टैगनाम है)

बाद में रेगेक्स में \1 का अर्थ है कि यह केवल उसी पाठ से मेल खाता है जो पहले समूह ( ([AZ][A-Z0-9]*) समूह में था) (इस मामले में यह अंत टैग से मेल खाता है )।





regex-group