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

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

Согласно Javadoc, (из того, что я понимаю), matches() will search the entire string even if it finds what it is looking for, and find() остановится, когда найдет то, что ищет.

Если это предположение верно, я не могу видеть, когда вы захотите использовать matches() вместо find(), unless you want to count the number of matches it finds.

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

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

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

5 ответов

Решение

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 и, следовательно, выводит ложь.

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

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

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

Найдено: ложь
Найдено: правда - позиция 4
Найдено: правда - позиция 17
Найдено: правда - позиция 20
Найдено: ложь
Найдено: ложь
Подходящий: ложный
-----------
Найдено: true - позиция 0
Найдено: ложь
Найдено: ложь
Подходит: правда
Подходит: правда
Подходит: правда
Подходит: правда

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

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

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 никогда не будет выполнен, поскольку первый символ совпадающей строки не является алфавитом.

Другие вопросы по тегам