Answers:
s = s.substring(0, Math.min(s.length(), 10));
这样使用Math.min
字符串可以避免在字符串早于的情况下出现异常10
。
笔记:
上面做了真正的修剪。如果您实际上想将截断的最后三个(!)字符替换为点,请使用Apache Commons StringUtils.abbreviate
。
如果您的字符串包含BMP之外的Unicode代码点,则此行为可能不正确1。例如表情符号。有关适用于所有Unicode代码点的(更复杂的)解决方案,请参见@sibnick的解决方案。
1-不在平面0(BMP)上的Unicode代码点在中表示为“代理对”(即两个char
值)String
。通过忽略这一点,我们可能会修剪到少于10个代码点,或者(更糟)在代理对中间截断。另一方面,String.length()
不再是Unicode文本长度的理想度量,因此基于它的修剪可能是错误的事情。
s = (s.length() > 10) ? s.substring(0,10) : s ;
StringUtils.abbreviate
来自Apache Commons Lang库的人可能是您的朋友:
StringUtils.abbreviate("abcdefg", 6) = "abc..."
StringUtils.abbreviate("abcdefg", 7) = "abcdefg"
StringUtils.abbreviate("abcdefg", 8) = "abcdefg"
StringUtils.abbreviate("abcdefg", 4) = "a..."
Commons Lang3甚至允许将自定义String设置为替换标记。这样,您可以例如设置单个字符的省略号。
StringUtils.abbreviate("abcdefg", "\u2026", 6) = "abcde…"
有一个Apache Commons StringUtils
函数可以做到这一点。
s = StringUtils.left(s, 10)
如果len个字符不可用,或者String为null,则将无例外返回String。如果len为负,则返回一个空字符串。
StringUtils.left(null,)= null
StringUtils.left(,-ve)=“”
StringUtils.left(“”,*)=“”
StringUtils.left(“ abc”,0)=“”
StringUtils.left(“ abc“,2)=” ab“
StringUtils.left(” abc“,4)=” abc“
图片提供:Steeve McCauley
像往常一样,没有人关心UTF-16代理对。请参阅以下内容:实际使用中最常见的非BMP Unicode字符是什么?甚至org.apache.commons / commons-lang3的作者
您可以在此示例中看到正确的代码和通常的代码之间的区别:
public static void main(String[] args) {
//string with FACE WITH TEARS OF JOY symbol
String s = "abcdafghi\uD83D\uDE02cdefg";
int maxWidth = 10;
System.out.println(s);
//do not care about UTF-16 surrogate pairs
System.out.println(s.substring(0, Math.min(s.length(), maxWidth)));
//correctly process UTF-16 surrogate pairs
if(s.length()>maxWidth){
int correctedMaxWidth = (Character.isLowSurrogate(s.charAt(maxWidth)))&&maxWidth>0 ? maxWidth-1 : maxWidth;
System.out.println(s.substring(0, Math.min(s.length(), correctedMaxWidth)));
}
}
或者,如果手边没有StringUtils,则可以使用此方法:
public static String abbreviateString(String input, int maxLength) {
if (input.length() <= maxLength)
return input;
else
return input.substring(0, maxLength-2) + "..";
}
System.out.println(abbreviateString("ABC\ud83d\udc3bDEF", 6));
截断时,您似乎在最后要求省略号(…
)。这是处理输入字符串的一种方法。
String input = "abcdefghijkl";
String output = ( input.length () > 10 ) ? input.substring ( 0 , 10 - 1 ).concat ( "…" ) : input;
abcdefghi ...
String input = "abcdefghijkl" ;
String output =
( input.length() > 10 ) // If too long…
?
input
.substring( 0 , 10 - 1 ) // Take just the first part, adjusting by 1 to replace that last character with an ellipsis.
.concat( "…" ) // Add the ellipsis character.
: // Or, if not too long…
input // Just return original string.
;
abcdefghi ...
从Java 9及更高版本开始,Java Streams工具使这一点变得有趣。有趣,但可能不是最佳方法。
我们使用代码点而不是char
值。该char
类型是旧的,并且限于所有可能的Unicode字符的子集。
String input = "abcdefghijkl" ;
int limit = 10 ;
String output =
input
.codePoints()
.limit( limit )
.collect( // Collect the results of processing each code point.
StringBuilder::new, // Supplier<R> supplier
StringBuilder::appendCodePoint, // ObjIntConsumer<R> accumulator
StringBuilder::append // BiConsumer<R,R> combiner
)
.toString()
;
如果我们有多余的字符被截断,请用省略号替换最后一个字符 。
if ( input.length () > limit )
{
output = output.substring ( 0 , output.length () - 1 ) + "…";
}
如果我能想到一种将流线与“如果超出限制,则省略号”部分放在一起的方法。