在Java中修剪字符串,同时保留完整的单词

Trim String in Java while preserve full word

我需要在Java中修剪字符串,以便:

The quick brown fox jumps over the laz dog.

变成

The quick brown...

在上面的示例中,我将裁剪为12个字符。如果我只使用子字符串,我会得到:

The quick br...

我已经有了一个使用子字符串来完成此操作的方法,但是我想知道哪种方法最快(最有效),因为一个页面可能有许多修剪操作。

我唯一能想到的方法是将字符串拆分成空格,然后将其放回一起,直到其长度超过给定的长度。还有别的办法吗?也许是一种更有效的方法,我可以使用相同的方法来进行"软"修剪,其中保留最后一个单词(如上面的示例所示),而硬修剪几乎是一个子串。

谢谢,


下面是我在webapps中用来修剪长字符串的方法。如您所说,"软"boolean,如果设置为true,将保留最后一个单词。这是我能想到的最简洁的方法,它使用的StringBuffer比重新创建一个不可变的字符串要高效得多。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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;

您可以删除它,代码也应该同样工作。


下面是一个简单的、基于regex的单线解决方案:

1
str.replaceAll("(?<=.{12})\\b.*","..."); // How easy was that!? :)

说明:

  • (?<=.{12})是一个否定的查找,它断言在匹配的左边至少有12个字符,但它是一个非捕获(即零宽度)匹配
  • \b.*将第一个单词边界(至少在上面12个字符之后)与结尾匹配

替换为"…"

这是一个测试:

1
2
3
4
5
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);
}

输出:

1
The quick brown...


请尝试以下代码:

1
2
3
4
5
6
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) +"...";
}


我使用这个方法:假设修剪后的字符串必须有120个长度:

1
2
3
4
5
6
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))+" ...";
        }

怎么样:

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


你的要求不明确。如果你在用自然语言表达它们的时候有困难,就不足为奇了,它们很难翻译成像Java那样的计算机语言。

"保留最后一个词"意味着算法将知道"词"是什么,所以您必须先告诉它。分裂是一种方式。另一种是带有语法的扫描器/解析器。

在我关心效率之前,我会先考虑让它发挥作用。让它工作,测量它,然后看看你能对性能做些什么。其他一切都是没有数据的推测。


尝试搜索位置小于或大于11的空格的最后一次出现,并通过添加"…"来修剪字符串。