根据某些条件在 Java 中截断字符串

String truncation in Java based on some conditions

我的要求是根据某些条件截断具有最大计数的字符串。条件是,

针对上面的需求我写了代码,但是当字符串有两个连续的字符如, ; 时它失败了。我的代码如下,

    public String getTruncateText(String text, int count) {
        int textLength = text.length();
        String truncatedText = text.substring(0, Math.min(count, textLength)).trim();
        int index = StringUtils.lastIndexOfAny(truncatedText,
                new String[] {" ",".",",",";",":","-","。","、",":",",",";"});
        return truncatedText.substring(0, index > 0 ? index : truncatedText.length()) + "...";
    }

    @Test
    public void Test() {
        String text = "I want to truncate text, Test"; 
        assertThat(getTruncateText(text, 15)).isEqualTo("I want to..."); //Success
        assertThat(getTruncateText(text, 25)).isEqualTo("I want to truncate text..."); //Success
        assertThat(getTruncateText(text, 1)).isEqualTo("I..."); //Success
        assertThat(getTruncateText(text, 2)).isEqualTo("I..."); //Success
        assertThat(getTruncateText(text, 300)).isEqualTo("I want to truncate text..."); //Failed
    }

由于我是 JAVA 世界的新手,对于糟糕的代码深表歉意...:)

提前致谢。干杯!!!

您可能需要 StringUtil.LastIndexOfAnyBut,其中 return 是不在给定字符集中的最后一个字符的索引。

我已经修复了解决方案,这里有几点需要指出。

    public static String getTruncateText(String text, int count) {
        String truncatedText = text.substring(0, Math.min(count, text.length())).trim();
        String[] endCharacters = new String[] {" ",".",",",";",":","-","。","、",":",",",";"};
        
        int index = StringUtils.lastIndexOfAny(truncatedText, endCharacters);
        truncatedText = truncatedText.substring(0, index >= 0 ? index : truncatedText.length());
        
        // Find index of the a non-ending character in the reversed string
        int indexReversed = StringUtils.indexOfAnyBut(StringUtils.reverse(truncatedText), String.join("", endCharacters)) ;
        // Subtracting index for reversed string from (the length of the truncate string - 1)
        index = indexReversed >= 0 ? truncatedText.length() - indexReversed - 1 : -1;
        
        // Because we want to include the character in this index, the end index for the substring is added by 1
        return truncatedText.substring(0, index >= 0 ? index + 1 : 0) + "...";
    }

原来,你在这里使用了index > 0,但是,当index=0时,“...”应该是return,但是index > 0会导致它转到else 分支,将文本的长度作为结束索引,并 returning 完整的字符串。

int index = StringUtils.lastIndexOfAny(truncatedText, endCharacters);
truncatedText = truncatedText.substring(0, index >= 0 ? index : truncatedText.length());

经过一些研究,我发现人们确实尝试为该库实现 lastIndexOfAnyBut,但它从未被添加到任何已发布的版本中。更多信息,您可以查看this thread.

所以我使用 indexOfAnyBut 而不是反向 truncatedText 来查找结束字符之前第一次出现的非结束字符(例如“我想截断 tex t, 测试").请注意,此处使用 String.join,因为 indexOfAnyBut 不接受 String[] 作为第二个参数。

// Find index of the a non-ending character in the reversed string
int indexReversed = StringUtils.indexOfAnyBut(StringUtils.reverse(truncatedText), String.join("", endCharacters)) ;
// Subtracting index for reversed string from (the length of the truncate string - 1)
index = indexReversed >= 0 ? truncatedText.length() - indexReversed - 1 : -1;