Разница между match() и find() в Java Regex

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

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

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

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

Итак, суммируем:

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

Ответ 1

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.

Ответ 2

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

Ответ 3

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 не был reset, даже если регулярное выражение окружено ^ и $ для соответствия полной строке.

Ответ 4

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

Ответ 5

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