Есть строки (их очень много) вида: String s1 = "10:11:23.555"
, т.е. формата hh::mm::ss.SSS. Нужно выделить минуты.
Пробовал так:
Pattern p = Pattern.compile("(\\:)(\\d+)(\\:)");
Matcher m = p.matcher(s1);
System.out.println(m.group());
Не помогло, возможно чего-то не понимаю.
Возможен другой подход: преобразовать исходную строку к какому-то формату Time, но на ходу не могу вспомнить подходящий класс.
Зачем использовать регулярное выражение для такой примитивной задачи?
String s1 = "10:11:23.555";
String[] tokens = s1.split(":");
String minutes = tokens[1];
UPDATE: Раз автор вопроса озабочен производительностью, а @MedvedevDev интересуется устройством String.split(), вопрос переходит в статус более-менее интересных, и я не могу не развернуть ответ.
Прежде всего надо заметить, что реализация методов стандартной библиотеки может отличаться в разных реализациях JVM или даже разных версиях одной и той же JVM. Причём метод может пробрасывать вызов в Сишный код, использующий SIMD-инструкции процессора, как это делает String.indexOf() например.
В Java 8 на HotSpot метод split
, как правильно заметил @Nick, использует регулярные выражения только для аргумента из нескольких символов или содержащего мета-символы. Иначе положения разделителя перебираются в цикле с помощью уже упомянутого мной indexOf
:
int off = 0;
int next = 0;
while ((next = indexOf(ch, off)) != -1) {
list.add(substring(off, next));
off = next + 1;
}
Посмотреть можно здесь.
Грешно было бы не проверить разницу в скорости между таким подходом и использованием регулярного выражения. Я набросал для этого тест JMH:
public class SplitBenchmark {
@State(Scope.Benchmark)
public static class BenchmarkState {
public List<String> strings;
public Pattern groupPattern;
public Pattern splitPattern;
@Setup(Level.Trial)
public void setup() {
groupPattern = Pattern.compile(":(\\d+):");
splitPattern = Pattern.compile(":");
Random random = new Random();
strings = IntStream.rangeClosed(0, 100_000)
.mapToObj(x -> random.ints(0, 99)
.mapToObj(i -> String.format("%02d", i))
.limit(3)
.collect(Collectors.joining(":")))
.collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
}
}
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void regexGroupMatching(BenchmarkState state, Blackhole blackhole) {
for (int i = 0; i < state.strings.size(); i++) {
String s = state.strings.get(i);
Matcher m = state.groupPattern.matcher(s);
if (m.find()) {
String minutes = m.group(1);
blackhole.consume(minutes);
}
}
}
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void regexPatternSplit(BenchmarkState state, Blackhole blackhole) {
for (int i = 0; i < state.strings.size(); i++) {
String s = state.strings.get(i);
String[] tokens = state.splitPattern.split(s);
String minutes = tokens[1];
blackhole.consume(minutes);
}
}
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void stringSplit(BenchmarkState state, Blackhole blackhole) {
for (int i = 0; i < state.strings.size(); i++) {
String s = state.strings.get(i);
String[] tokens = s.split(":");
String minutes = tokens[1];
blackhole.consume(minutes);
}
}
}
Результат:
Benchmark Mode Cnt Score Error Units
SplitBenchmark.regexGroupMatching avgt 25 10,382 ? 0,120 ms/op
SplitBenchmark.regexPatternSplit avgt 25 17,235 ? 0,240 ms/op
SplitBenchmark.stringSplit avgt 25 7,906 ? 0,069 ms/op
Как можно видеть, String.split()
самый быстрый, а Pattern.split()
существенно медленнее даже извлечения групп, чем я сам удивлён.
Чем не устроил метод substring
?
String s1 = "10:11:23.555";
String minutes = s1.substring(3, 5);
System.out.println(minutes);
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Какие существуют виды рекламных бордов и как выбрать подходящий?
Какая разница между Cascade types в Hibernate и ON DELETE/UPDATE actions в SQLНужно ли менять ON UPDATE/ON DELETE на Cascade для коректного использования CascadeType в Hibernate?
На данный вопрос уже ответили:
Проблема с библиотекой fancybox до этого не работал с ней поэтому не могу понять в чем ошибка (при клике на ссылку происходит обычный переброс...