Подтвердить что ты не робот

Какая разница между String.matches и Matcher.matches?

Какая разница между String.matches и Matcher.matches? Есть ли разница в производительности или других вещах?

4b9b3361

Ответ 1

Совершенно верно. A Matcher создается в предварительно скомпилированном регулярном выражении, а String.matches должен перекомпилировать регулярное выражение каждый раз, когда он выполняется, поэтому он становится более расточительным, чем чаще вы запускаете эту строку кода.

Ответ 2

String.matches внутренне делегирует Matcher.matches.

public boolean matches(String regex) {
    return Pattern.matches(regex, this);
}

public static boolean matches(String regex, CharSequence input) {
    Pattern p = Pattern.compile(regex);
    Matcher m = p.matcher(input);
    return m.matches();
}

Если вы повторно используете объект Pattern, тогда будет некоторое преимущество в производительности. Также при использовании Pattern/Matcher вы можете group ваши регулярные выражения и получить соответствующие части.

Если вы используете регулярное выражение, которое вы будете использовать только один раз, и вам не нужно анализировать вашу строку, чтобы получить соответствующие части, то используйте их. Но если вы собираетесь использовать одно и то же регулярное выражение для нескольких строк или вам нужны части строки на основе регулярного выражения, создайте шаблон и получите его, используя его.

Ответ 3

Из любопытства я сделал этот небольшой тест по разнице во времени. Оказывается, что с использованием предварительно скомпилированного шаблона более чем в 5 раз быстрее, чем с использованием метода String.matches.

import java.util.regex.Pattern;

/**
 * @author Rajind Ruparathna
 */
public class MatchesTest {
    public static void main(String Args[]) {
        String first = "@\\{message.headers\\.?([^\\}]*)\\}";
        String second = "@\\{message.headers.wolla\\}";
        long start, end, total;
        float avg;
        int NUM_OF_ITERATIONS = 100;

        Pattern pattern = Pattern.compile(first);

        total = 0;
        start = 0;
        end = 0;
        avg = 0;

        for (int i=0; i< NUM_OF_ITERATIONS; i++) {
            start = System.nanoTime();
            pattern.matcher(second).matches();
            end = System.nanoTime();
            total = total + (end - start);
        }
        avg = total/NUM_OF_ITERATIONS;
        System.out.println("Duration pre compiled: " + avg);

        total = 0;
        start = 0;
        end = 0;
        avg = 0;

        for (int i=0; i< NUM_OF_ITERATIONS; i++) {
            start = System.nanoTime();
            first.matches(second);
            end = System.nanoTime();
            total = total + (end - start);
        }
        avg = total/NUM_OF_ITERATIONS;
        System.out.println("In place compiled: " + avg);
    }
}

Выход (наносекунды):

Продолжительность предварительной компиляции: 4505.0

Скомпилировано: 44960.0

Ответ 4

String.matches внутренне вызывает Pattern.matches(regex, str). Проблема заключается в том, что каждый раз, когда вы его называете, вы перекомпилируете шаблон, который стоит несколько ресурсов.

Лучше скомпилировать свой шаблон один раз, а затем попытаться сопоставить его со всеми необходимыми строками. Я лично использую класс Patterns, содержащий все мои шаблоны в моем приложении, объявленные как final и static

Ответ 6

Pattern.compile компилирует шаблон таким образом, что при выполнении metcher.matches шаблон снова не компилируется снова и снова. Pattern.compile pre компилирует его. Однако, если вы используете string.matches, он компилирует шаблон каждый раз, когда вы выполняете эту строку. Итак, лучше использовать Pattern.compile.