Обрезать возможный префикс строки в Java
У меня есть String str
, из которого я хочу извлечь подстроку, исключая возможный префикс "abc"
.
Первое решение, которое приходит на ум:
if (str.startsWith("abc"))
return str.substring("abc".length());
return str;
Мои вопросы:
-
Существует ли "чистый" способ сделать это с помощью split
и регулярного выражения для префикса "abc"
?
-
Если да, то он менее эффективен, чем метод выше (потому что он выполняет поиск по всей строке)?
-
Если да, есть ли лучший способ сделать это (где "лучший способ" = чистое и эффективное решение)?
Обратите внимание, что префикс "abc"
может появляться в другом месте строки и не должен быть удален.
Спасибо
Ответы
Ответ 1
Короче, чем выше код, будет эта строка:
return str.replaceFirst("^abc", "");
Но с точки зрения производительности я предполагаю, что не будет существенной разницы между двумя кодами. Один использует регулярное выражение и не использует регулярное выражение, но выполняет поиск и подстроку.
Ответ 2
Использование String.replaceFirst
с ^abc
(для соответствия ведущему abc
)
"abcdef".replaceFirst("^abc", "") // => "def"
"123456".replaceFirst("^abc", "") // => "123456"
"123abc456".replaceFirst("^abc", "") // => "123abc456"
Ответ 3
- Использование
String#split
может сделать это, но это не лучшее решение. На самом деле это будет неопределенным, и я бы не рекомендовал использовать его для этой цели.
- Не тратьте время на эффективность в этом случае, это не важно, сосредоточьтесь на логике и ясности. Но обратите внимание, что работа с регулярным выражением обычно медленнее, поскольку она включает дополнительные операции, поэтому вы можете сохранить
startsWith
.
- Ваш подход прекрасен, если вы хотите проверить, начинается ли String с "abc",
String#startsWith
.
Вы можете легко измерить время выполнения кода. Вот что вы можете сделать:
Создайте большой цикл, внутри него вы можете добавить счетчик его в какую-то фиктивную строку, чтобы имитировать строки, которые вы хотите проверить, затем попробуйте startsWith
один раз и replaceAll
после:
for(int i = 0;i<900000;i++) {
StringBuilder sb = new StringBuilder("abc");
sb.append(i);
if(sb.toString().startsWith("abc")) { ... }
}
long time = System.currentTimeMillis() - start;
System.out.println(time); //Prints ~130
for(int i = 0;i<900000;i++){
StringBuilder sb = new StringBuilder("abc");
sb.append(i);
sb.toString().replaceAll("^abc", "");
}
long time = System.currentTimeMillis() - start;
System.out.println(time); //Prints ~730
Ответ 4
Попробуйте это
str = str.replaceAll("^abc", "");
Ответ 5
Решение, свободное от регулярных выражений (мне это нужно, потому что строка, которую я удаляю, настраивается и содержит обратную косую черту, которая требует ускорения для литералов в регулярном выражении):
Apache Commons Lang StringUtils.removeStart(str, remove)
удалит remove
с начала str
с помощью String.startsWith
и String.substring
.
исходный код метода информативен:
public static String removeStart(final String str, final String remove) {
if (isEmpty(str) || isEmpty(remove)) {
return str;
}
if (str.startsWith(remove)){
return str.substring(remove.length());
}
return str;
}
Ответ 6
Что касается эффективности, вы можете использовать StringBuilder
, где у вас есть несколько операций над одной строкой, например подстрока, затем поиск индекса, затем подстрока и т.д.
Если речь идет о чистоте/эффективности, можно использовать StringUtils (Apache Commons Lang)
.
Надеюсь, что это поможет.