Bir normal ifade için eşleşme sayısını nasıl sayabilirim?


99

Diyelim ki bunu içeren bir dizem var:

HelloxxxHelloxxxHello

'Merhaba' aramak için bir model derliyorum

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

Üç kibrit bulmalı. Kaç tane eşleşme olduğunu nasıl öğrenebilirim?

Çeşitli döngüler denedim ve kullanıyorum matcher.groupCount()ama işe yaramadı.


Arama dizenizin giriş dizesinde çakışan olaylar olma ihtimali var mı?
aioobe

Yanıtlar:


178

matcher.find()tüm eşleşmeleri bulmaz , sadece sonraki eşleşmeyi bulur .

Java 9+ için Çözüm

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

Java 8 ve daha eski sürümler için çözüm

Aşağıdakileri yapmanız gerekecek. ( Java 9'dan başlayarak, daha güzel bir çözüm var )

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

Btw, matcher.groupCount()tamamen farklı bir şey.

Tam örnek :

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
    }
}

Çakışan eşleşmeleri işleme

Karşılaşmalar sayarken aade aaaayukarıdaki pasajı size verecektir 2 .

aaaa
aa
  aa

3 eşleşme elde etmek için, yani bu davranış:

aaaa
aa
 aa
  aa

<start of last match> + 1Aşağıdaki gibi dizinde bir eşleşme aramanız gerekir :

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

Dize içinde gerçekleşen eşleşmelerin sayılması. Java.util.regex.Matcher.region (int start, int end) yöntemi bu eşleştiricinin bölgesinin sınırlarını belirler. Bölge, bir eşleşme bulmak için aranacak giriş dizisinin parçasıdır. Bu yöntemi çağırmak, eşleştiriciyi sıfırlar ve ardından bölgeyi başlangıç ​​parametresi tarafından belirtilen dizinde başlayacak ve bitiş parametresi tarafından belirtilen dizinde bitecek şekilde ayarlar. Bunu dene. while(matcher.find()){ matcher.region(matcher.end()-1, str.length()); count++; }
Mukesh Kumar Gupta

17

Bu, çakışabilecek eşleşmeler için çalışmalıdır:

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

Java 8 akışlarını kullanmak istiyorsanız ve whiledöngülere alerjiniz varsa, şunu deneyebilirsiniz:

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();
}

Sorumluluk reddi: bu yalnızca ayrık maçlar için işe yarar.

Misal:

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));
}

Bu çıktı:

2
0
1
0

Bu, akışlarla ayrık eşleşmeler için bir çözümdür:

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

Normal ifadenin girişinizde bulduğu eşleşme sayısını bulmak için aşağıdaki kodu kullanın

        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++;

Bu, spesifik olmayan genelleştirilmiş bir koddur, ihtiyacınıza göre uyarlayın

Herhangi bir hata varsa lütfen beni düzeltmekten çekinmeyin.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.