Обрезка строки в 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.

" сохранить последнее слово "означает, что алгоритм будет знать, что такое" слово", поэтому вам придется сначала сказать ему это. Раскол-это способ сделать это. Сканер / парсер с грамматикой-это другое.

Я бы беспокоился о том, чтобы заставить его работать, прежде чем я беспокоился об эффективности. Заставьте его работать, измерьте его, а затем посмотрите, что вы можете сделать с производительностью. Все остальное-спекуляции без данных.


Как насчет:

mystring = mystring.replaceAll("^(.{12}.*?)\b.*$", "...");

Я использую этот хак: предположим, что обрезанная строка должна иметь 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))+ " ...";
        }