Если вы собираетесь часто вызывать метод, лучшее, что вы можете сделать, это , а не , скомпилировать шаблон внутри него. В противном случае, каждый раз, когда вы вызываете метод, вы тратите больше времени на создание регулярного выражения, чем на его поиск.
Но, посмотрев на ваш код еще раз, я думаю, что у вас есть большая проблема с точки зрения производительности. Все, что нужно для поиска «ISBN» и создания подстрок для применения регулярных выражений, совершенно не нужно. Позвольте регулярному выражению делать это; это то, для чего они. Следующее регулярное выражение находит "ISBN" дозорного и следующие тринадцать цифр, если они там есть:
static final Pattern isbnPattern = Pattern.compile(
"\\bISBN[^A-Z0-9]*+(\\d(?:-*+\\d){12})", Pattern.CASE_INSENSITIVE );
[^A-Z0-9]*+
поглощает любые символы, которые могут появиться между "ISBN" и первой цифрой. Собственный квантификатор (*+
) предотвращает ненужный возврат; если следующий символ не является цифрой, механизм регулярных выражений немедленно завершает эту попытку сопоставления и возобновляет сканирование для другого экземпляра «ISBN».
Я использовал другой собственнический квантификатор для необязательных дефисов, плюс группу без захвата ((?:...)
) для повторной части; это дает еще один небольшой выигрыш в производительности по сравнению с группами захвата, используемыми большинством других респондентов. Но я использовал группу захвата для целого числа, чтобы его можно было легко извлечь из общего совпадения. С этими изменениями ваш метод сводится к следующему:
public String parseISBN (String source) {
Matcher m = isbnPattern.matcher(source);
return m.find() ? m.group(1) : null;
}
... и это гораздо эффективнее. Обратите внимание, что мы не рассмотрели, как строки попадают в память. Если вы выполняете ввод-вывод самостоятельно, возможно, в этой области также будет достигнут существенный прирост производительности.