Taglia una stringa in base alla lunghezza della stringa


136

Voglio tagliare una stringa se la lunghezza supera i 10 caratteri.

Supponiamo che la lunghezza della stringa sia 12 ( String s="abcdafghijkl"), conterrà la nuova stringa tagliata "abcdefgh..".

Come posso raggiungere questo obiettivo?


6
possibile duplicato di un massimo di primi N caratteri
Stephen C

Cordiali saluti, un ELLIPSIS ORIZZONTALE è un singolo personaggio, non due o tre personaggi FULL STOP : ...
Basil Bourque

Risposte:


262
s = s.substring(0, Math.min(s.length(), 10));

L'uso in Math.minquesto modo evita un'eccezione nel caso in cui la stringa sia già più corta di 10.


Appunti:

  1. Quanto sopra fa il vero taglio. Se vuoi effettivamente sostituire gli ultimi tre (!) Caratteri con punti se si tronca, usa Apache Commons StringUtils.abbreviate.

  2. Ciò potrebbe comportarsi in modo errato 1 se la stringa contiene codici codificati Unicode all'esterno del BMP; ad esempio Emoji. Per una soluzione (più complicata) che funzioni correttamente per tutti i punti di codice Unicode, vedere la soluzione di @ sibnick .


1 - Un punto di codice Unicode che non si trova sul piano 0 (BMP) è rappresentato come una "coppia surrogata" (cioè due charvalori) in String. Ignorando questo, potremmo tagliare a meno di 10 punti di codice, o (peggio) troncare nel mezzo di una coppia surrogata. D'altra parte, String.length()non è più una misura ideale della lunghezza del testo Unicode, quindi il taglio basato su di esso potrebbe essere la cosa sbagliata da fare.


Invece di Math.min non possiamo fare un controllo condizionale e fare la sottostringa solo se la stringa è max allora è richiesta? ad esempio:s = (s.length() > 10) ? s.substring(0,10) : s ;
1919

1
Sì, certo che puoi. Leggi le altre risposte per altri modi di risolvere il problema!
Stephen C,

132

StringUtils.abbreviatedalla biblioteca Lang di Apache Commons potrebbe essere tuo amico:

StringUtils.abbreviate("abcdefg", 6) = "abc..."
StringUtils.abbreviate("abcdefg", 7) = "abcdefg"
StringUtils.abbreviate("abcdefg", 8) = "abcdefg"
StringUtils.abbreviate("abcdefg", 4) = "a..."

Commons Lang3 consente persino di impostare una stringa personalizzata come marker di sostituzione. Con questo puoi ad esempio impostare un puntino di sospensione a singolo carattere.

StringUtils.abbreviate("abcdefg", "\u2026", 6) = "abcde…"

5
Potrebbe essere, ma la domanda del PO non richiede "puntini di sospensione".
Stephen C,

9
@StephenC - La domanda mostra 8 caratteri seguiti da 2 punti, dato un limite di lunghezza di 10, che è molto simile a un'ellissi (solo 2 punti anziché 3). È anche probabile che molte persone che trovano questa domanda considerino utili le ellissi.
ToolmakerSteve

12
... e se non vuoi i puntini di sospensione, allora StringUtils.left () può aiutarti.
Superole,

1
Cordiali saluti, un ELLIPSIS ORIZZONTALE è un singolo personaggio, non tre personaggi FULL STOP :…
Basil Bourque

53

C'è una StringUtilsfunzione di Apache Commons che lo fa.

s = StringUtils.left(s, 10)

Se i caratteri len non sono disponibili o la stringa è nulla, la stringa verrà restituita senza eccezioni. Viene restituita una stringa vuota se len è negativo.

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

Per gentile concessione: Steeve McCauley


22

Come al solito a nessuno importa delle coppie surrogate UTF-16. Vedi di loro: Quali sono i caratteri Unicode non BMP più comuni attualmente in uso? Perfino autori di org.apache.commons / commons-lang3

In questo esempio puoi vedere la differenza tra il codice corretto e il solito codice:

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

1
Trovato il bug nella jira dei beni comuni di Apache: issues.apache.org/jira/browse/LANG-1343
Ryan Quinn

10

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


16
Il secondo parametro di sottostringa è esclusivo, quindi questa risposta limita la stringa a 9 caratteri.
emulcahy,

8

Oppure puoi semplicemente usare questo metodo nel caso in cui StringUtils non sia a portata di mano:

public static String abbreviateString(String input, int maxLength) {
    if (input.length() <= maxLength) 
        return input;
    else 
        return input.substring(0, maxLength-2) + "..";
}

Il tuo codice non ha funzionato per me. Prova questoSystem.out.println(abbreviateString("ABC\ud83d\udc3bDEF", 6));
T3rm1

4

Nel caso in cui tu stia cercando un modo per tagliare e mantenere gli ULTIMI 10 caratteri di una stringa.

s = s.substring(Math.max(s.length(),10) - 10);

3

Con Kotlin è semplice come:

yourString.take(10)

Restituisce una stringa contenente i primi n caratteri di questa stringa o l'intera stringa se questa stringa è più corta.

Documentazione


1

tl; dr

Sembra che tu stia chiedendo un carattere di puntino di sospensione ( ) nell'ultimo posto, quando troncati. Ecco un one-liner per manipolare la tua stringa di input.

String input = "abcdefghijkl";
String output = ( input.length () > 10 ) ? input.substring ( 0 , 10 - 1 ).concat ( "…" ) : input;

Vedi questo codice eseguito dal vivo su IdeOne.com.

abcdefghi ...

Operatore ternario

Siamo in grado di creare un one-liner usando l' operatore ternario .

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

Vedi questo codice eseguito dal vivo su IdeOne.com.

abcdefghi ...

Flussi Java

La funzione Java Streams lo rende interessante, a partire da Java 9 e versioni successive. Interessante, ma forse non è l'approccio migliore.

Utilizziamo i punti di codice anziché i charvalori. Il chartipo è legacy ed è limitato al sottoinsieme di tutti i possibili caratteri 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()
        ;

Se abbiamo troncato i caratteri in eccesso, sostituisci l'ultimo carattere con i puntini di sospensione .

if ( input.length () > limit )
{
    output = output.substring ( 0 , output.length () - 1 ) + "…";
}

Se solo potessi pensare a un modo per mettere insieme la linea di flusso con la parte "if over limit, do ellipsis".


No. Chiaramente, vuole tagliare la lunghezza della corda se raggiunge una lunghezza di 11 o più. Devi lavorare su un nuovo sistema di intelligenza artificiale oO
JD333

1
@ JD333 Il tuo commento mi sfugge. Troncare a una lunghezza di 10 inclusi i puntini di sospensione è esattamente ciò che mostro qui.
Basil Bourque,

0
str==null ? str : str.substring(0, Math.min(str.length(), 10))

o,

str==null ? "" : str.substring(0, Math.min(str.length(), 10))

Funziona con null.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.