मैं रेगेक्स के लिए मैचों की संख्या कैसे गिन सकता हूं?


97

मान लीजिए कि मेरे पास एक स्ट्रिंग है जिसमें यह शामिल है:

HelloxxxHelloxxxHello

मैं 'हैलो' देखने के लिए एक पैटर्न संकलित करता हूं

Pattern pattern = Pattern.compile("Hello");
Matcher matcher = pattern.matcher("HelloxxxHelloxxxHello");

इसे तीन मैच खोजने चाहिए। मुझे इस बात की गिनती मिल सकती है कि कितने मैच थे?

मैं विभिन्न छोरों की कोशिश की है और उपयोग कर रहा है, matcher.groupCount()लेकिन यह काम नहीं किया।


किसी भी मौका आपके खोज स्ट्रिंग इनपुट स्ट्रिंग में अतिव्यापी घटनाओं हो सकता है?
aioobe

जवाबों:


177

matcher.find()सभी मैच नहीं मिल रहे हैं, केवल अगले मैच।

जावा 9+ के लिए समाधान

long matches = matcher.results().count();

जावा 8 और पुराने के लिए समाधान

आपको निम्न कार्य करने होंगे। ( जावा 9 से शुरू, एक अच्छा समाधान है )

int count = 0;
while (matcher.find())
    count++;

Btw, matcher.groupCount()कुछ पूरी तरह से अलग है।

पूरा उदाहरण :

import java.util.regex.*;

class Test {
    public static void main(String[] args) {
        String hello = "HelloxxxHelloxxxHello";
        Pattern pattern = Pattern.compile("Hello");
        Matcher matcher = pattern.matcher(hello);

        int count = 0;
        while (matcher.find())
            count++;

        System.out.println(count);    // prints 3
    }
}

ओवरलैपिंग मैचों को संभालना

जब से मैचों की गिनती aaमें aaaaऊपर टुकड़ा आप दे देंगे 2

aaaa
aa
  aa

3 मैच पाने के लिए, अर्थात यह व्यवहार:

aaaa
aa
 aa
  aa

आपको सूचकांक पर एक मैच के लिए खोज करनी <start of last match> + 1है:

String hello = "aaaa";
Pattern pattern = Pattern.compile("aa");
Matcher matcher = pattern.matcher(hello);

int count = 0;
int i = 0;
while (matcher.find(i)) {
    count++;
    i = matcher.start() + 1;
}

System.out.println(count);    // prints 3

स्ट्रिंग के भीतर होने वाले मैचों की संख्या की गणना। Java.util.regex.Matcher.region (int start, int end) विधि इस मिलानकर्ता के क्षेत्र की सीमा निर्धारित करती है। क्षेत्र इनपुट अनुक्रम का एक हिस्सा है जिसे एक मैच खोजने के लिए खोजा जाएगा। इस विधि को लागू करने से मिलानकर्ता रीसेट करता है, और फिर प्रारंभ पैरामीटर द्वारा निर्दिष्ट इंडेक्स पर शुरू करने के लिए और अंत पैरामीटर द्वारा निर्दिष्ट इंडेक्स पर अंत करने के लिए क्षेत्र सेट करता है। इसे इस्तेमाल करे। while(matcher.find()){ matcher.region(matcher.end()-1, str.length()); count++; }
मुकेश कुमार गुप्ता

17

यह उन मैचों के लिए काम करना चाहिए जो ओवरलैप हो सकते हैं:

public static void main(String[] args) {
    String input = "aaaaaaaa";
    String regex = "aa";
    Pattern pattern = Pattern.compile(regex);
    Matcher matcher = pattern.matcher(input);
    int from = 0;
    int count = 0;
    while(matcher.find(from)) {
        count++;
        from = matcher.start() + 1;
    }
    System.out.println(count);
}


3

यदि आप जावा 8 स्ट्रीम का उपयोग करना चाहते हैं और whileलूप से एलर्जी है , तो आप यह कोशिश कर सकते हैं:

public static int countPattern(String references, Pattern referencePattern) {
    Matcher matcher = referencePattern.matcher(references);
    return Stream.iterate(0, i -> i + 1)
            .filter(i -> !matcher.find())
            .findFirst()
            .get();
}

डिस्क्लेमर: यह केवल डिसऑइंट मैच के लिए काम करता है।

उदाहरण:

public static void main(String[] args) throws ParseException {
    Pattern referencePattern = Pattern.compile("PASSENGER:\\d+");
    System.out.println(countPattern("[ \"PASSENGER:1\", \"PASSENGER:2\", \"AIR:1\", \"AIR:2\", \"FOP:2\" ]", referencePattern));
    System.out.println(countPattern("[ \"AIR:1\", \"AIR:2\", \"FOP:2\" ]", referencePattern));
    System.out.println(countPattern("[ \"AIR:1\", \"AIR:2\", \"FOP:2\", \"PASSENGER:1\" ]", referencePattern));
    System.out.println(countPattern("[  ]", referencePattern));
}

यह प्रिंट करता है:

2
0
1
0

यह धाराओं के साथ मेल खाने वाले मेलों के लिए एक समाधान है:

public static int countPattern(String references, Pattern referencePattern) {
    return StreamSupport.stream(Spliterators.spliteratorUnknownSize(
            new Iterator<Integer>() {
                Matcher matcher = referencePattern.matcher(references);
                int from = 0;

                @Override
                public boolean hasNext() {
                    return matcher.find(from);
                }

                @Override
                public Integer next() {
                    from = matcher.start() + 1;
                    return 1;
                }
            },
            Spliterator.IMMUTABLE), false).reduce(0, (a, c) -> a + c);
}

1

नीचे दिए गए कोड का उपयोग करके अपने इनपुट में रेगेक्स की संख्या की संख्या का पता लगाएं

        Pattern p = Pattern.compile(regex, Pattern.MULTILINE | Pattern.DOTALL);// "regex" here indicates your predefined regex.
        Matcher m = p.matcher(pattern); // "pattern" indicates your string to match the pattern against with
        boolean b = m.matches();
        if(b)
        count++;
        while (m.find())
        count++;

यह एक सामान्यीकृत कोड है जो विशिष्ट नहीं है, फिर भी इसे अपनी आवश्यकता के अनुरूप बनाएं

अगर कोई गलती हो तो कृपया मुझे सुधारने के लिए स्वतंत्र महसूस करें।

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