首页 > 解决方案 > Java中基于某些条件的字符串截断

问题描述

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

对于上述要求,我编写了代码,但是当字符串有两个连续的字符(如, 和)时它会失败; 。我的代码如下,

    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 世界的新手,因此为糟糕的代码道歉...... :)

提前致谢。干杯!!!

标签: javaapache-stringutilsstring-utils

解决方案


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

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

    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 时,应该返回“...”,但index > 0会导致它转到 else 分支,将文本的长度作为结束索引并返回完整的字符串反而。

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

做了一些研究,我发现人们确实尝试lastIndexOfAnyBut为这个库实现,但它从未被添加到任何发布的版本中。有关更多信息,您可以查看此线程

所以我使用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;

推荐阅读