Обрезка строки в Java при сохранении полного слова
Мне нужно обрезать строку в java так, чтобы:
быстрая коричневая лиса перепрыгивает через собаку лаз.
становится
быстрая коричневая...
в приведенном выше примере я обрезаю до 12 символов. Если я просто использую подстроку, я получу:
быстрый br...
У меня уже есть метод для этого с помощью подстроки, но я хотел знать, что является самым быстрым (большинство эффективный) способ сделать это, потому что страница может иметь много обрезать операций.
единственный способ, которым я могу думать, это разделить строку на пробелы и собрать ее обратно, пока ее длина не пройдет заданную длину. Есть ли другой способ? Возможно, более эффективный способ, которым я могу использовать тот же метод, чтобы сделать "мягкую" обрезку, где я сохраняю последнее слово (как показано в примере выше) и жесткую обрезку, которая в значительной степени является подстрокой.
спасибо,
7 ответов
Ниже приведен метод, который я использую для обрезки длинных строк в моих webapps.
"Мягкий"boolean
Как вы выразились, если значение true
сохранить последнее слово.
Это самый краткий способ сделать это, который я мог бы придумать, который использует StringBuffer, который намного эффективнее, чем воссоздание строки, которая неизменяема.
public static String trimString(String string, int length, boolean soft) {
if(string == null || string.trim().isEmpty()){
return string;
}
StringBuffer sb = new StringBuffer(string);
int actualLength = length - 3;
if(sb.length() > actualLength){
// -3 because we add 3 dots at the end. Returned string length has to be length including the dots.
if(!soft)
return escapeHtml(sb.insert(actualLength, "...").substring(0, actualLength+3));
else {
int endIndex = sb.indexOf(" ",actualLength);
return escapeHtml(sb.insert(endIndex,"...").substring(0, endIndex+3));
}
}
return string;
}
обновление
Я изменил код так, что ...
добавляется в StringBuffer, это для предотвращения ненужного творения String
неявно, что медленно и расточительно.
Примечание: escapeHtml
является статическим импортом из Apache commons:
import static org.apache.commons.lang.StringEscapeUtils.escapeHtml;
вы можете удалить его и код должен работать одинаково.
вот простое, основанное на регулярных выражениях, 1-строчное решение:
str.replaceAll("(?<=.{12})\b.*", "..."); // How easy was that!? :)
пояснение:
-
(?<=.{12})
- это отрицательный взгляд назад, который утверждает, что есть по крайней мере 12 символов слева от матча, но это не захват (т. е. нулевая ширина) матч -
\b.*
соответствует первой границе слова (после по крайней мере 12 символов - выше) до конца
Это заменить "..."
здесь тест:
public static void main(String[] args) {
String input = "The quick brown fox jumps over the lazy dog.";
String trimmed = input.replaceAll("(?<=.{12})\b.*", "...");
System.out.println(trimmed);
}
выход:
The quick brown...
пожалуйста, попробуйте следующий код:
private String trim(String src, int size) {
if (src.length() <= size) return src;
int pos = src.lastIndexOf(" ", size - 3);
if (pos < 0) return src.substring(0, size);
return src.substring(0, pos) + "...";
}
попробуйте найти последнее появление пространства, которое находится в положении меньше или больше 11, и обрезать строку там, добавив "...".
ваши требования не ясны. Если у вас возникли проблемы с их артикуляцией на естественном языке, неудивительно, что их будет трудно перевести на компьютерный язык, такой как Java.
" сохранить последнее слово "означает, что алгоритм будет знать, что такое" слово", поэтому вам придется сначала сказать ему это. Раскол-это способ сделать это. Сканер / парсер с грамматикой-это другое.
Я бы беспокоился о том, чтобы заставить его работать, прежде чем я беспокоился об эффективности. Заставьте его работать, измерьте его, а затем посмотрите, что вы можете сделать с производительностью. Все остальное-спекуляции без данных.
Я использую этот хак: предположим, что обрезанная строка должна иметь 120 длины:
String textToDisplay = textToTrim.substring(0,(textToTrim.length() > 120) ? 120 : textToTrim.length());
if (textToDisplay.lastIndexOf(' ') != textToDisplay.length() &&textToDisplay.length()!=textToTrim().length()) {
textToDisplay = textToDisplay + textToTrim.substring(textToDisplay.length(),textToTrim.indexOf(" ", textToDisplay.length()-1))+ " ...";
}