Je veux couper une chaîne si la longueur dépasse 10 caractères.
Supposons que si la longueur de la chaîne est 12 (String s="abcdafghijkl"
), la nouvelle chaîne coupée contiendra "abcdefgh.."
.
Comment puis-je atteindre cet objectif?
s = s.substring(0, Math.min(s.length(), 10));
Utiliser Math.min
comme ceci évite une exception dans le cas où la chaîne est déjà plus courte que 10
.
Remarques:
La description ci-dessus est réelle. Si vous souhaitez réellement remplacer les trois (!) Derniers caractères par des points s’il est tronqué, utilisez Apache Commons StringUtils.abbreviate
.
Cela peut se comporter de manière incorrecte1 si votre chaîne contient des points de code Unicode en dehors du BMP; par exemple. Emojis. Pour une solution (plus compliquée) qui fonctionne correctement pour tous les points de code Unicode, voir @ sibnick's solution .
1 - Un point de code Unicode qui n'est pas dans le plan 0 (le BMP) est représenté par une "paire de substitution" (c'est-à-dire deux valeurs char
) dans le String
. En ignorant cela, nous pourrions réduire à moins de 10 points de code, ou (pire) tronquer au milieu d'une paire de substitution. Par contre, String.length()
n'est plus une mesure idéale de la longueur du texte Unicode. Par conséquent, le rognage en fonction de cette longueur peut être une mauvaise chose à faire.
StringUtils.abbreviate
de Apache Commons Lang La bibliothèque pourrait être votre amie:
_StringUtils.abbreviate("abcdefg", 6) = "abc..."
StringUtils.abbreviate("abcdefg", 7) = "abcdefg"
StringUtils.abbreviate("abcdefg", 8) = "abcdefg"
StringUtils.abbreviate("abcdefg", 4) = "a..."
_
Il existe une fonction StringUtils
qui le fait.
s = StringUtils.left(s, 10)
Si les caractères len ne sont pas disponibles ou si la chaîne est null, la chaîne sera renvoyée sans exception. Une chaîne vide est renvoyée si len est négatif.
StringUtils.left (null, ) = null
StringUtils.left (, -ve) = ""
StringUtils.left ("", *) = ""
StringUtils.left ("abc", 0) = ""
StringUtils.left ("abc", 2) = "ab"
StringUtils.left ("abc", 4) = "abc"
Gracieuseté de Steeve McCauley
Comme d'habitude, personne ne se soucie des paires de substitution UTF-16. Voir à ce sujet: Quels sont les caractères Unicode non-BMP les plus utilisés actuellement? Même les auteurs de org.Apache.commons/commons-lang3
Vous pouvez voir la différence entre le code correct et le code habituel dans cet exemple:
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)));
}
}
s = s.length() > 10 ? s.substring(0, 9) : s;
Ou vous pouvez simplement utiliser cette méthode si vous n'avez pas StringUtils sous la main:
public static String abbreviateString(String input, int maxLength) {
if (input.length() <= maxLength)
return input;
else
return input.substring(0, maxLength-2) + "..";
}
Juste au cas où vous cherchiez un moyen de couper et de conserver les 10 derniers caractères d'une chaîne.
s = s.substring(Math.max(s.length(),10) - 10);
Avec Kotlin, c'est aussi simple que:
yourString.take(10)
Retourne une chaîne contenant les n premiers caractères de cette chaîne, ou la chaîne entière si cette chaîne est plus courte.
str==null ? str : str.substring(0, Math.min(str.length(), 10))
ou,
str==null ? "" : str.substring(0, Math.min(str.length(), 10))
Fonctionne avec null.
Vous semblez demander un caractère Ellipsis (…
) à la dernière place, lors de la troncature. Voici un one-liner pour manipuler votre chaîne d’entrée.
String input = "abcdefghijkl";
String output = ( input.length () > 10 ) ? input.substring ( 0 , 10 - 1 ).concat ( "…" ) : input;
Voir ceci code exécuté en direct chez IdeOne.com.
abcdefghi…
Nous pouvons faire un one-liner en utilisant le opérateur ternaire .
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.
;
Voir ceci code exécuté en direct chez IdeOne.com.
abcdefghi…
La fonction Java Streams rend cela intéressant, à partir de Java 9 et versions ultérieures. Intéressant, mais peut-être pas la meilleure approche.
Nous utilisons points de code plutôt que char
valeurs. Le type char
est hérité et se limite aux n sous-ensemble de tous les caractères nicode possibles.
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()
;
Si nous avions des caractères excédentaires tronqués, remplacez le dernier caractère par un Ellipsis .
if ( input.length () > limit )
{
output = output.substring ( 0 , output.length () - 1 ) + "…";
}
Si seulement je pouvais penser à un moyen de mettre en place la ligne de flux avec la partie "Si la limite est dépassée, faites Ellipsis".