Quale metodo nella classe String restituisce solo i primi N caratteri?


184

Vorrei scrivere un metodo di estensione nella Stringclasse in modo che se la stringa di input è più lunga della lunghezza fornita N, Nvengano visualizzati solo i primi caratteri.

Ecco come appare:

public static string TruncateLongString(this string str, int maxLength)
{
    if (str.Length <= maxLength)
        return str;
    else
        //return the first maxLength characters                
}

Quale String.*()metodo posso usare per ottenere solo i primi Ncaratteri di str?

Risposte:


374
public static string TruncateLongString(this string str, int maxLength)
{
    if (string.IsNullOrEmpty(str))
        return str;
    return str.Substring(0, Math.Min(str.Length, maxLength));
}

6
Math.Min è necessario? Pensavo che Substring sapesse che se il secondo parametro fosse maggiore della lunghezza, avrebbe semplicemente inserito la lunghezza?
Martin,

12
Credo che sia: System.String.InternalSubStringWithChecks lancerebbe ArgumentOutOfRange.
Paul Ruane,

2
@Martin: non che io possa vedere, startIndex > (this.Length - length)lancia un ArgumentOutOfRangeException.
user7116

2
Stavo per suggerire di verificare se Math.Min(str.Length, maxLength) == str.Lengthnel caso in cui si finisse per creare una stringa non necessaria per restituire "i primi caratteri str. Di lunghezza di str", ma Sottostringa lo fa per te e lo fa solo return thisse hai chiesto l'intera stringa.
Stevemegson,

2
Se si desidera che il metodo di estensione funzioni su stringhe potenzialmente nulle ... return str? .Substring (0, Math.Min (str.Length, maxLength));
ihake,

62
string truncatedToNLength = new string(s.Take(n).ToArray());  

Questa soluzione ha un piccolo vantaggio in quanto se n è maggiore di s.Length, fa ancora la cosa giusta.


9
Sì, ma usando Linq per troncare una stringa? Basta essere consapevoli che questo funzionerà molto male se usato molte volte come in un ciclo. Non farlo per abitudine
ErikE

31

Puoi usare LINQ str.Take(n)o str.SubString(0, n), dove quest'ultimo genererà ArgumentOutOfRangeExceptionun'eccezionen > str.Length .

Presente che la versione LINQ restituisce una IEnumerable<char>, in modo che avrebbe dovuto convertire il IEnumerable<char>a string: new string(s.Take(n).ToArray()).


10
Non usare Linq per troncare le stringhe. È ridicolo.
ErikE

17

Ogni volta che devo fare manipolazioni di stringhe in C #, mi mancano le buone vecchie Lefte le Rightfunzioni di Visual Basic, che sono molto più semplici da usare rispetto aSubstring .

Quindi nella maggior parte dei miei progetti C #, creo metodi di estensione per loro:

public static class StringExtensions
{
    public static string Left(this string str, int length)
    {
        return str.Substring(0, Math.Min(length, str.Length));
    }

    public static string Right(this string str, int length)
    {
        return str.Substring(str.Length - Math.Min(length, str.Length));
    }
}

Nota:
la Math.Minparte è presente perché Substringgenera un ArgumentOutOfRangeExceptionquando la lunghezza della stringa di input è inferiore alla lunghezza richiesta, come già menzionato in alcuni commenti nelle risposte precedenti.

Uso:

string longString = "Long String";

// returns "Long";
string left1 = longString.Left(4);

// returns "Long String";
string left2 = longString.Left(100);

Mi piace questo, ma se la stringa fosse più corta della lunghezza data, non aggiungerebbe spazi. public static string Left(this string str, int length) { var Result = str.Substring(0, Math.Min(length, str.Length)); return (Result.Length < length) ? Result.PadRight(length) : Result; }
Grandizer,

strdeve essere verificato per null
liviriniu

14

Semplicemente:

public static String Truncate(String input,int maxLength)
{
   if(input.Length > maxLength)
      return input.Substring(0,maxLength);
   return input;
}

7
public static string TruncateLongString(this string str, int maxLength)
{
    return str.Length <= maxLength ? str : str.Remove(maxLength);
}

1
Inoltre, str == null || str.Length <= maxLength
tieni

6
Per chiunque si chieda se Removeo Substringè meglio, non c'è differenza. Remove(maxLength)chiama solo Substring(0,maxLength)dopo un po 'di controllo dei limiti. Quale preferisci dipende dal fatto che tu pensi al troncamento come "prendi i primi caratteri maxLength" o "butta via tutto dopo i caratteri maxLength". Certo, è davvero entrambi, quindi dipende da te.
Stevemegson,

5

se stiamo parlando di convalide anche perché non abbiamo verificato la presenza di voci di stringa null. Qualche motivo specifico?

Penso di seguito aiuto poiché IsNullOrEmpty è un metodo definito dal sistema e gli operatori ternari hanno complessità ciclomatica = 1 mentre if () {} else {} ha valore 2.

    public static string Truncate(string input, int truncLength)
    {
        return (!String.IsNullOrEmpty(input) && input.Length >= truncLength)
                   ? input.Substring(0, truncLength)
                   : input;
    }

qual è il problema con la complessità ciclomatica 2?
Muflix,

1

Ho aggiunto questo nel mio progetto solo perché dove lo sto usando è un'alta probabilità che venga utilizzato in loop, in un progetto ospitato online quindi non volevo arresti anomali se potevo gestirlo. La lunghezza corrisponde a una colonna che ho. È C # 7

Solo una riga:

 public static string SubStringN(this string Message, int Len = 499) => !String.IsNullOrEmpty(Message) ? (Message.Length >= Len ? Message.Substring(0, Len) : Message) : "";

0

Il metodo .NET Substring è pieno di pericoli. Ho sviluppato metodi di estensione che gestiscono un'ampia varietà di scenari. La cosa bella è che conserva il comportamento originale, ma quando si aggiunge un parametro "vero" aggiuntivo, si ricorre al metodo di estensione per gestire l'eccezione e restituisce i valori più logici, in base all'indice e alla lunghezza. Ad esempio, se la lunghezza è negativa e conta indietro. Puoi vedere i risultati del test con un'ampia varietà di valori sul violino su: https://dotnetfiddle.net/m1mSH9 . Questo ti darà un'idea chiara di come risolve le sottostringhe.

Aggiungo sempre questi metodi a tutti i miei progetti e non devo mai preoccuparmi della violazione del codice, perché qualcosa è cambiato e l'indice non è valido. Di seguito è riportato il codice.

    public static String Substring(this String val, int startIndex, bool handleIndexException)
    {
        if (!handleIndexException)
        { //handleIndexException is false so call the base method
            return val.Substring(startIndex);
        }
        if (string.IsNullOrEmpty(val))
        {
            return val;
        }
        return val.Substring(startIndex < 0 ? 0 : startIndex > (val.Length - 1) ? val.Length : startIndex);
    }

    public static String Substring(this String val, int startIndex, int length, bool handleIndexException)
    {
        if (!handleIndexException)
        { //handleIndexException is false so call the base method
            return val.Substring(startIndex, length);
        }
        if (string.IsNullOrEmpty(val))
        {
            return val;
        }
        int newfrom, newlth, instrlength = val.Length;
        if (length < 0) //length is negative
        {
            newfrom = startIndex + length;
            newlth = -1 * length;
        }
        else //length is positive
        {
            newfrom = startIndex;
            newlth = length;
        }
        if (newfrom + newlth < 0 || newfrom > instrlength - 1)
        {
            return string.Empty;
        }
        if (newfrom < 0)
        {
            newlth = newfrom + newlth;
            newfrom = 0;
        }
        return val.Substring(newfrom, Math.Min(newlth, instrlength - newfrom));
    }

Ho scritto questo blog nel maggio 2010 su: http://jagdale.blogspot.com/2010/05/substring-extension-method-that-does.html


0

In parte per motivi di riepilogo (esclusa la soluzione LINQ), ecco due linee guida che affrontano l' int maxLengthavvertenza di consentire valori negativi e anche il caso di stringa nulla:

  1. Il Substringmodo (dalla risposta di Paul Ruane ):
public static string Truncate(this string s, uint maxLength) =>
    s?.Substring(0, Math.Min(s.Length, (int)maxLength));
  1. Il Removemodo (dalla risposta di kbrimington ):
public static string Truncate(this string s, uint maxLength) =>
    s?.Length > maxLength ? s.Remove((int)maxLength) : s;

-1
substring(int startpos, int lenght);

-4

string.Substring (0, n); // 0 - inizio indice e n - numero di caratteri


4
A differenza della risposta accettata, ciò può causare errori di indice fuori limite.
Servito il
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.