Обрезать строку в Java при сохранении полного слова - PullRequest
9 голосов
/ 12 октября 2011

Мне нужно обрезать строку в java так, чтобы:

Быстрая коричневая лиса перепрыгнула через лазу.

становится

Быстрый коричневый ...

В приведенном выше примере я обрезаю до 12 символов.Если бы я просто использовал подстроку, я бы получил:

Быстрый br ...

У меня уже есть метод для этого с использованием подстроки, но я хотел знать, чтоэто самый быстрый (самый эффективный) способ сделать это, потому что на странице может быть много операций обрезки.

Единственный способ, о котором я могу подумать, - это разбить строку на пробелы и сложить обратно, пока ее длина не пройдетзаданная длина.Есть ли другой способ?Возможно, более эффективный способ, с помощью которого я могу использовать тот же метод для «мягкой» обрезки, где я сохраняю последнее слово (как показано в примере выше) и жесткую обрезку, которая в значительной степени является подстрокой.

Спасибо

Ответы [ 7 ]

11 голосов
/ 12 октября 2011

Ниже приведен метод, который я использую для обрезки длинных строк в моих веб-приложениях. «Soft» 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;

Вы можете удалить его, и код должен работать так же.

8 голосов
/ 12 октября 2011

Вот простое решение на основе регулярных выражений, состоящее из 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...
4 голосов
/ 12 октября 2011

Пожалуйста, попробуйте следующий код:

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) + "...";
}
0 голосов
/ 12 января 2015

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

Как насчет:

mystring = mystring.replaceAll("^(.{12}.*?)\b.*$", "$1...");
0 голосов
/ 12 октября 2011

Ваши требования не ясны. Если вам сложно сформулировать их на естественном языке, неудивительно, что их будет трудно перевести на компьютерный язык, такой как Java.

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

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

0 голосов
/ 12 октября 2011

Попробуйте найти последнее вхождение пробела, который находится в позиции меньше или больше 11, и обрежьте строку, добавив «...».

...