2013-07-31 6 views
103

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

मेरी समझ यह है कि यह किसी भी चरित्र (0 या अधिक बार *) के बाद किसी भी वर्ण (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"); 
     } 
    } 

} 
+0

एक नई लाइन डालने के लिए, लाइन के अंत में 2 रिक्त स्थान रखें। मार्कडाउन सिंटैक्स के बारे में अधिक जानकारी: http://en.wikipedia.org/wiki/Markdown - यह भी देखें: http: //stackoverflow.com/editing-help – assylias

उत्तर

158

आपको आ रही समस्या परिमाणक के प्रकार के साथ है। , यह कर सकते हैं (और के बाद से यह किसी भी चरित्र है, यह हूँ जितना की भरपाई करेंगे जिसका मतलब है - आप अपने पहले समूह में एक लालची परिमाणक (सूचकांक 0 पूरे Pattern का प्रतिनिधित्व करता सूचकांक) का उपयोग कर रहे अगले समूहों के लिए स्थिति को पूरा करने के लिए कई वर्ण के रूप में मिलान करें)।

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

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

आप अपने 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)); 
} 

आउटपुट: जावा Patternhere पर

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

अधिक जानकारी।

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

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

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

+0

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

+0

@Xivilai मुझे अपने जवाब में सिर्फ एक सेकंड में मेरी व्याख्या को ठीक करने दें। – Mena

+0

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

3

आपकी समझ सही है। हालांकि, अगर हम आगे बढ़ते हैं:

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

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

1
डॉक से

:

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 पूरी लाइन भेजने पर कब्जा।

11

यह बिल्कुल ठीक है।

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

बनाम आलसी लालची बारे में अधिक जानकारी के लिए, जाँच this site.

संबंधित मुद्दे