जावा रेगेक्स कैप्चरिंग समूह


170

मैं इस कोड ब्लॉक को समझने की कोशिश कर रहा हूं। पहले एक में, यह हम अभिव्यक्ति में क्या देख रहे हैं?

मेरी समझ यह है कि यह किसी भी वर्ण (0 या अधिक बार *) के बाद 0 और 9 के बीच किसी भी संख्या (एक या अधिक बार +) के बाद किसी भी वर्ण (0 या अधिक बार *) के बाद है।

जब यह निष्पादित किया जाता है तो परिणाम होता है:

Found value: This order was placed for QT3000! OK?
Found value: This order was placed for QT300
Found value: 0

किसी कृपया मेरे साथ इस के माध्यम से जा सकते हैं?

कैप्चरिंग समूहों का उपयोग करने का क्या फायदा है?

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexTut3 {

    public static void main(String args[]) {
        String line = "This order was placed for QT3000! OK?"; 
        String pattern = "(.*)(\\d+)(.*)";

        // Create a Pattern object
        Pattern r = Pattern.compile(pattern);

        // Now create matcher object.
        Matcher m = r.matcher(line);

        if (m.find()) {
            System.out.println("Found value: " + m.group(0));
            System.out.println("Found value: " + m.group(1));
            System.out.println("Found value: " + m.group(2));
        } else {
            System.out.println("NO MATCH");
        }
    }

}

1
नई पंक्ति डालने के लिए, पंक्ति के अंत में 2 रिक्त स्थान रखें।
मार्कडाउन

जवाबों:


248

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

संक्षेप में, आपका पहला समूह .*तब तक कुछ भी मेल खाता है जब तक कि अगला समूह \\d+किसी चीज़ से मेल खा सकता है (इस मामले में, अंतिम अंक)।

तीसरे समूह के अनुसार, यह अंतिम अंक के बाद कुछ भी मैच करेगा।

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

1 समूह में प्रश्न चिह्न पर ध्यान दें ।

String line = "This order was placed for QT3000! OK?";
Pattern pattern = Pattern.compile("(.*?)(\\d+)(.*)");
Matcher matcher = pattern.matcher(line);
while (matcher.find()) {
    System.out.println("group 1: " + matcher.group(1));
    System.out.println("group 2: " + matcher.group(2));
    System.out.println("group 3: " + matcher.group(3));
}

आउटपुट:

group 1: This order was placed for QT
group 2: 3000
group 3: ! OK?

जावा पर अधिक जानकारी Pattern यहाँ

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

जावा में 6 समूहों को केवल उनके आदेश (नेस्टेड समूहों से सावधान और आदेश देने की सूक्ष्मता) द्वारा संदर्भित किया जा सकता है।

जावा 7 में यह बहुत आसान है, क्योंकि आप नामित समूहों का उपयोग कर सकते हैं।


धन्यवाद! क्या कारण समूह 2 को 0 संग्रहीत किया गया है क्योंकि पूरी लाइन लालची क्वांटिफायर द्वारा खपत की गई थी जो तब तक वापस आ गई जब तक कि यह एक या अधिक संख्याओं के संपर्क में नहीं आया। 0 इससे संतुष्ट हो गए ताकि अभिव्यक्ति सफल हो गई। मैं तीसरे समूह को भ्रमित करता हुआ पाता हूं, क्या वह लालची क्वांटिफायर भी पूरी लाइन का उपभोग करता है, लेकिन जब तक वह एक या एक से अधिक संख्या (\\ d +) का पता नहीं लगा लेता, जो उसे पूर्ववर्ती माना जाता है?
१२:२२ पर Xivilai

@Xivilai मुझे मेरे जवाब में मेरे स्पष्टीकरण को ठीक करने दें, बस एक सेकंड।
मेना

यह एक अच्छी व्याख्या है। तो अनिच्छुक बाईं ओर से शुरू होता है और सिर्फ लालच के साथ न्यूनतम लेता है, जितना संभव हो सकता है (दाईं ओर से शुरू), केवल उस स्थिति को संतुष्ट करने के लिए अंतिम अंक से पहले रुक जाता है। तीसरा समूह बाकी लेता है।
Xivilai

@Xivilai कमोबेश। यह हमेशा इस मामले में बाईं ओर से शुरू होता है। यहां क्वांटिफायर के बारे में कुछ और जानकारी दी गई है।
मेना

2
आप जावा 5/6 में नामांकित कैप्चर समूहों का उपयोग कर सकते हैं named-regexp

16

यह पूरी तरह से ठीक है।

  1. पहला समूह ( m.group(0)) हमेशा पूरे क्षेत्र को पकड़ता है जो आपकी नियमित अभिव्यक्ति से आच्छादित है । इस मामले में, यह पूरी स्ट्रिंग है।
  2. नियमित अभिव्यक्तियां डिफ़ॉल्ट रूप से लालची होती हैं, जिसका अर्थ है कि पहला समूह रेगेक्स का उल्लंघन किए बिना जितना संभव हो सके, कब्जा कर लेता है। (.*)(\\d+)(अपने regex के पहले भाग) को शामिल किया गया ...QT300पूर्णांक पहले समूह और 0दूसरे में।
  3. परिवर्तन: आप जल्दी से पहले समूह गैर लालची बनाकर इसे ठीक कर सकते (.*)करने के लिए (.*?)

लालची बनाम आलसी पर अधिक जानकारी के लिए, इस साइट की जाँच करें।


4

डॉक्टर से:

Capturing groups</a> are indexed from left
 * to right, starting at one.  Group zero denotes the entire pattern, so
 * the expression m.group(0) is equivalent to m.group().

तो समूह 0 पर कब्जा पूरी लाइन भेजें।


3

आपकी समझ सही है। हालाँकि, अगर हम इससे गुजरते हैं:

  • (.*) पूरे तार निगल जाएगा;
  • इसे वापस वर्ण देने की आवश्यकता होगी ताकि (\\d+)व्यंग्य हो (जो इसीलिए 0पकड़ा गया हो, न कि 3000);
  • आखिरी (.*)तो बाकी पर कब्जा कर लेंगे।

मुझे यकीन नहीं है कि लेखक का मूल इरादा क्या था, हालांकि।

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