web-dev-qa-db-fra.com

Couper une chaîne en fonction de la longueur de la chaîne

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?

110
yshak
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:

  1. 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.

  2. 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.

216
Stephen C

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..."
_
108
H6.

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"

StringUtils.Left JavaDocs

Gracieuseté de Steeve McCauley

41
Mulki

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)));
    }
}
16
sibnick

s = s.length() > 10 ? s.substring(0, 9) : s;

10
shift66

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) + "..";
}
7
MVojtkovszky

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);
4
rekotc

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.

Documentation

3
Leo Droidcoder
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.

0
aceminds

tl; dr

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…

Opérateur ternaire

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…

Flux Java

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".

0
Basil Bourque