根据某些条件在 Java 中截断字符串
String truncation in Java based on some conditions
我的要求是根据某些条件截断具有最大计数的字符串。条件是,
- 字符串的长度不能超过最大计数
- 不能像
I want to trun
那样以半字结尾
- 字符串的结尾由
{" ",".",",",";",":","-","。","、",":",",",";"}
中的下列字符之一决定,该字符必须替换为...
针对上面的需求我写了代码,但是当字符串有两个连续的字符如,
和;
时它失败了。我的代码如下,
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;
我的要求是根据某些条件截断具有最大计数的字符串。条件是,
- 字符串的长度不能超过最大计数
- 不能像
I want to trun
那样以半字结尾
- 字符串的结尾由
{" ",".",",",";",":","-","。","、",":",",",";"}
中的下列字符之一决定,该字符必须替换为...
针对上面的需求我写了代码,但是当字符串有两个连续的字符如,
和;
时它失败了。我的代码如下,
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;