Разница между match () и find () в Java Regex - PullRequest
225 голосов
/ 15 декабря 2010

Я пытаюсь понять разницу между matches() и find().

Согласно Javadoc, (из того, что я понимаю), matches() будет искать всю строку, даже если найдет то, что ищет, и find() остановится, когда найдет то, что ищет.

Если это предположение верно, я не смогу увидеть, когда вы это сделаетеЯ хочу использовать matches() вместо find(), если только вы не хотите подсчитать количество найденных совпадений.

По моему мнению, класс String должен иметь find() вместо matches() в качестве встроенногометод.

Итак, подведем итог:

  1. Правильно ли мое предположение?
  2. Когда полезно использовать matches() вместо find()?

Ответы [ 5 ]

276 голосов
/ 15 декабря 2010

matches пытается сопоставить выражение со всей строкой и неявно добавить ^ в начале и $ в конце шаблона, то есть он не будет искать подстроку.Следовательно, вывод этого кода:

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
*/

123 является подстрокой a123b, поэтому метод find() выводит true.matches() только «видит» a123b, который не совпадает с 123, и, следовательно, выдает false.

73 голосов
/ 15 декабря 2010

matches возвращает true, если вся строка соответствует заданному шаблону.find пытается найти подстроку, соответствующую шаблону.

50 голосов
/ 23 августа 2013

matches() вернет true, только если найдена полная строка. find() попытается найти следующее вхождение в подстроке, соответствующей регулярному выражению. Обратите внимание на акцент на «следующий». Это означает, что результат вызова 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());

Будет выводить:

Found: false
Found: true - position 4
Found: true - position 17
Found: true - position 20
Found: false
Found: false
Matched: false
-----------
Found: true - position 0
Found: false
Found: false
Matched: true
Matched: true
Matched: true
Matched: true

Итак, будьте осторожны при многократном вызове find(), если объект Matcher не был сброшен, даже когда регулярное выражение окружено ^ и $ для соответствия полной строке.

5 голосов
/ 10 февраля 2017

find() будет рассматривать подстроку против регулярного выражения, где matches() будет считать полное выражение.

find() вернет true, только если подстрока выражения соответствует шаблону.

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 голосов
/ 16 марта 2016

matches(); не буферизует, но find() буферизует. find() сначала выполняет поиск до конца строки, индексирует результат и возвращает логическое значение и соответствующий индекс.

Вот почему, когда у вас есть код вроде

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

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

3:int count = 0;

4:while(matcher.find()){

5:count++: }

В 4: Движок регулярных выражений, использующий структуру шаблона, прочитает весь ваш код (индекс для индексации, как указано regex[single character], чтобы найти хотя бы одно соответствие. Если такое совпадение найдено , он будет проиндексирован, тогда цикл будет выполняться на основе индексированного результата, в противном случае он не будет выполнять предварительное вычисление, как это делает matches(); оператор while никогда не будет выполнен, поскольку первый символ соответствующей строки не является алфавит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...