Java Regex'te match () ve find () arasındaki fark


250

Ben arasındaki farkı anlamaya çalışıyorum matches()ve find().

Javadoc'a göre, (anladığım kadarıyla), matches()aradığı şeyi bulsa bile tüm dizeyi arayacak ve aradığı find()şeyi bulduğunda duracaktır.

Bu varsayım doğruysa, ben kullanmak isteyeyim zaman göremiyorum matches()yerine find()sen bulduğu eşleşme sayısını saymak istemedikçe.

Benim düşünceme göre String sınıfı, dahili bir yöntem find()yerine olmalıdır matches().

Özetlemek gerekirse:

  1. Varsayım doğru mu?
  2. matches()Bunun yerine ne zaman kullanılır find()?

2
find()Birden çok kez çağırmanın , bunun için farklı sonuçlar döndürebileceğini unutmayın Matcher. Cevabımı aşağıda görebilirsiniz.
L. Holanda

Yanıtlar:


300

matchesçalışır, tüm dize karşı ifadeyle eşleşen ve örtük bir ekleme ^başında ve $bir alt dizeyi aramaz, yani senin desen sonunda. Bu nedenle bu kodun çıktısı:

public static void main(String[] args) throws ParseException {
    Pattern p = Pattern.compile("\\d\\d\\d");
    Matcher m = p.matcher("a123b");
    System.out.println(m.find());
    System.out.println(m.matches());

    p = Pattern.compile("^\\d\\d\\d$");
    m = p.matcher("123");
    System.out.println(m.find());
    System.out.println(m.matches());
}

/* output:
true
false
true
true
*/

123de bir alt a123byüzden find()yöntem doğru çıkış olarak vermektedir. matches()sadece 'görmez' a123b, ki bu aynı değildir 123ve sonuç olarak yanlış çıkar.


25
Bu cevap yanıltıcı. matchers()sadece bir find()zımni çevreleyen ^ ve $ ile değil. .find()Birden fazla çağrının , önceden alınmamışsa farklı sonuçları olabileceğini reset(), ancak matches()her zaman aynı sonucu döndüreceğini unutmayın. Cevabımı aşağıda görebilirsiniz.
L. Holanda

80

matchestüm dize verilen kalıpla eşleşirse true değerini döndürür. findkalıpla eşleşen bir alt dize bulmaya çalışır.


35
Bunun daha net matches(p)olduğu gibi find("^" + p + "$")olduğunu söyleyebilirsiniz .
jensgram

4
Cevabı açıklığa kavuşturmak için sadece bir örnek: "123abc123" dizesiyle "[az] +" eşleşmeler () kullanılarak başarısız olur, ancak find () kullanılarak başarılı olur.
bezmax

3
@Max Tam olarak, "123abc123".matches("[a-z]+")olduğu gibi başarısız "123abc123".find("^[a-z]+$")olur. Demek matches()istediğim find(), hem başlangıç ​​hem de bitiş çapalarında olduğu gibi tam bir eşleşme için geçerliydi.
jensgram

5
Pattern.compile("some pattern").matcher(str).matches()eşittirPattern.compile("^some pattern$").matcher(str).find()
AlexR

3
@AlexR / @jensgram: ...("some pattern").matcher(str).matches()edilir değil tam karşı eşit ...("^some pattern$").matcher(str).find()ilk çağrısında tek gerçek o yıllardan. Cevabımı aşağıda görebilirsiniz.
L. Holanda

62

matches()yalnızca tam dize eşleşirse true değerini döndürür. alt dizede normal ifadeyle eşleşen bir sonraki olayı find()bulmaya çalışır . "Bir sonraki" konusuna dikkat edin. Bu, birden çok kez çağrılmanın sonucu aynı olmayabilir. Ayrıca, kullanarak alt dizenin eşleştiği konumu döndürmek için arayabilirsiniz .find()find()start()

final Matcher subMatcher = Pattern.compile("\\d+").matcher("skrf35kesruytfkwu4ty7sdfs");
System.out.println("Found: " + subMatcher.matches());
System.out.println("Found: " + subMatcher.find() + " - position " + subMatcher.start());
System.out.println("Found: " + subMatcher.find() + " - position " + subMatcher.start());
System.out.println("Found: " + subMatcher.find() + " - position " + subMatcher.start());
System.out.println("Found: " + subMatcher.find());
System.out.println("Found: " + subMatcher.find());
System.out.println("Matched: " + subMatcher.matches());

System.out.println("-----------");
final Matcher fullMatcher = Pattern.compile("^\\w+$").matcher("skrf35kesruytfkwu4ty7sdfs");
System.out.println("Found: " + fullMatcher.find() + " - position " + fullMatcher.start());
System.out.println("Found: " + fullMatcher.find());
System.out.println("Found: " + fullMatcher.find());
System.out.println("Matched: " + fullMatcher.matches());
System.out.println("Matched: " + fullMatcher.matches());
System.out.println("Matched: " + fullMatcher.matches());
System.out.println("Matched: " + fullMatcher.matches());

Çıktı olacak:

Bulunan: yanlış
Bulunan: doğru - konum 4
Bulunan: doğru - konum 17
Bulunan: doğru - konum 20
Bulunan: yanlış
Bulunan: yanlış
Eşleşme: yanlış
-----------
Bulunan: doğru - konum 0
Bulunan: yanlış
Bulunan: yanlış
Eşleşme: gerçek
Eşleşme: gerçek
Eşleşme: gerçek
Eşleşme: gerçek

Çağrılırken Yani, dikkatli olun find()eğer birden çok kez Matchernesne sıfırlamak değildi regex ile çevrilidir bile, ^ve $tam dize eşleşecek.


2
very helpful mate
DockYard

6

find()tam dizeyi dikkate alacağı şekilde normal ifadeye karşı alt dizeyi matches()dikkate alır.

find() yalnızca ifadenin alt dizesi kalıpla eşleşirse true değerini döndürür.

public static void main(String[] args) {
        Pattern p = Pattern.compile("\\d");
        String candidate = "Java123";
        Matcher m = p.matcher(candidate);

        if (m != null){
            System.out.println(m.find());//true
            System.out.println(m.matches());//false
        }
    }

3

matches();tampon yapmaz, find()tampon yapar. find()önce dizenin sonuna bakar, sonucu dizine ekler ve boole değerini ve karşılık gelen dizini döndürür.

Bu yüzden şöyle bir kodunuz olduğunda

1:Pattern.compile("[a-z]");

2:Pattern.matcher("0a1b1c3d4");

3:int count = 0;

4:while(matcher.find()){

5:count++: }

At 4: belirttiği gibi kod indeksine (endeks bütün okuyacaktır desen yapısı kullanılarak regex motoru regex[single character]. Böyle eşleşme bulunursa, o zaman endeksli olacak en az bir eşleşme bulmak için döngü dayalı yürütmek olacak bunun gibi önceden hesaplama yapmadıysa, dizinlenmiş sonuç başka bir şey matches()yapmaz, eşleşen deyimin ilk karakteri bir alfabe olmadığından while ifadesi hiçbir zaman yürütülmez.

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.