Come posso ottenere gli ultimi quattro caratteri da una stringa in C #?


309

Supponiamo che io abbia una stringa:

"34234234d124"

Voglio ottenere gli ultimi quattro caratteri di questa stringa che è "d124". Posso usare SubString, ma ha bisogno di un paio di righe di codice, incluso il nome di una variabile.

È possibile ottenere questo risultato in un'espressione con C #?


3
Cosa vuoi quando ci sono meno di 4 caratteri?
agente-j

12
4 > mystring.length ? mystring : mystring.Substring(mystring.length -4);
Jodrell,

3
In Python la soluzione è semplice: "hello world"[-4:]. Spero che una futura versione di C # lo renda facile.
Colonnello Panic,

@ColonelPanic, ora puoi con C # 8.0: "hello world"[^4..]:-)
Frode Evensen,

Risposte:


407
mystring.Substring(Math.Max(0, mystring.Length - 4)); //how many lines is this?

Se sei positivo, la lunghezza della tua stringa è almeno 4, quindi è ancora più corta:

mystring.Substring(mystring.Length - 4);

13
Inoltre, fallirà se mystringè lungo meno di 4 caratteri.
George Duckett,

3
+1 perché penso che il tuo sia leggermente più leggibile di @ dtb's
George Duckett,

Prendere un paio di righe di codice (che l'OP già conosceva) e stiparle su una riga non è proprio la stessa cosa di un'espressione.
Buh Buh,

1
Mi piace. Semplice ed elegante e prende il massimo, quindi se la tua stringa è inferiore a 0 non otterrai un'eccezione fuori indice.
Brettico

+1 semplice e al punto, copre tutte le basi. Anche il metodo di estensione proposto da Stecya è buono, ma è un po 'eccessivo se lo fai solo una volta.
Morvael,

205

È possibile utilizzare un metodo di estensione :

public static class StringExtension
{
    public static string GetLast(this string source, int tail_length)
    {
       if(tail_length >= source.Length)
          return source;
       return source.Substring(source.Length - tail_length);
    }
}

E poi chiama:

string mystring = "34234234d124";
string res = mystring.GetLast(4);

11
Mi piace, ma probabilmente lo chiamerei Last (). Dopotutto Substring () non è GetSubstring ().
Buh Buh,

21
Forse chiamalo Tail () come Last si scontra con l'estensione Linq Last ().
Craig Curtis il

5
+1 per averlo reso "molto più lungo di 1 riga". È così fastidioso vedere il codice illeggibile a causa del risparmio di linea.
Fabio Milheiro,

2
O chiamalo Right () per coerenza con VisualBasic secondo la risposta del programmatore @RJ (non voglio aggiungere un altro assembly solo per una funzione).
christutty,

3
Adoro questa soluzione.
Luca

46

Tutto quello che devi fare è ..

String result = mystring.Substring(mystring.Length - 4);

2
Non se vuoi che venga generata un'eccezione se la lunghezza è inferiore a 4 ...
Milos Mrdovic

45

Ok, quindi vedo che questo è un vecchio post, ma perché stiamo riscrivendo il codice che è già fornito nel framework?

Suggerirei di aggiungere un riferimento alla DLL del framework "Microsoft.VisualBasic"

using Microsoft.VisualBasic;
//...

string value = Strings.Right("34234234d124", 4);

8
Un bell'esempio di tempo per usare la funzionalità VB
Brian White

3
Ti amo. Gran parte della mia esperienza di programmazione è VB, quindi scoprire che posso usare tutte quelle funzioni con cui ho così familiarità è fantastico
Ben Strombeck,

6
Non riesco mai a capire se usare MS.VB sia una buona idea - perché viene deviato nello VisualBasicspazio dei nomi? TextFieldParserè un altro esempio. Perché queste utility vengono prese in considerazione in modo così strano?
ruffin,

6
Sento che questa dovrebbe essere la risposta accettata. Perché reinventare la ruota?
Zack

2
@Bomboca: possiamo essere certi che continuerà finché Microsoft continuerà a supportare Visual Basic. È incluso nella versione 4.6 e non riesco a trovare nulla di esplicito o implicito da parte di MS che prevedono di smettere di supportare VB.Net come linguaggio di sviluppo.
Programmatore RJ,

30
string mystring = "34234234d124";
mystring = mystring.Substring(mystring.Length-4)

26

L'uso del sottostringa è in realtà abbastanza breve e leggibile:

 var result = mystring.Substring(mystring.Length - Math.Min(4, mystring.Length));
 // result == "d124"

17

Ecco un'altra alternativa che non dovrebbe funzionare troppo male (a causa dell'esecuzione differita ):

new string(mystring.Reverse().Take(4).Reverse().ToArray());

Sebbene un metodo di estensione allo scopo mystring.Last(4)sia chiaramente la soluzione più pulita, anche se un po 'più di lavoro.


1
@BrianWhite Le persone sono irritabili dopo il capodanno?
Konrad Viltersten,

1
Bella soluzione. mi piace. Ma hai dimenticato l'altro Reverse per ottenere la stringa corretta. Deve essere: new string (mystring.Reverse (). Take (4) .Reverse (). ToArray ());
Yuri Morales,

Aah sì, hai ragione - il mio compilatore mentale non ha pensato così lontano. Purtroppo questo lo fa sembrare ancora peggio! :)
Andre Luus,

1
A causa di ToArray non c'è esecuzione differita

1
Non credo che tu capisca, @ BjörnAliGöransson, il mio punto era che Reverse().Take(4).Reverse()non elencano tutti l'intera stringa, succede solo nell'ultima ToArraychiamata. Se non esistesse un'esecuzione differita, si tradurrebbe in Reverse().ToArray().Take(4).ToArray().Reverse().ToArray(). Questo, ovviamente, presuppone che quelle estensioni siano di tipo differito, cosa che non ho verificato. I costruttori di stringhe non accettano IEnumerable, quindi è necessario enumerarlo in un array in quel punto.
Andre Luus,

17

Puoi semplicemente usare il Substringmetodo di C #. Per es.

string str = "1110000";
string lastFourDigits = str.Substring((str.Length - 4), 4);

Restituirà il risultato 0000.


7
Questa è stata risposta come 28 volte e l'hai aggiunta di nuovo? E perché usare il sovraccarico a due parametri invece di quello che riceve solo startIndex?
Andrew,

Esattamente la risposta di cui avevo bisogno. Grazie per aver condiviso @Amit Kumawat.
Daryl,

12

Una soluzione semplice sarebbe:

string mystring = "34234234d124";
string last4 = mystring.Substring(mystring.Length - 4, 4);

7
mystring = mystring.Length > 4 ? mystring.Substring(mystring.Length - 4, 4) : mystring;

Bello, ma penso che tu =non intendessi =+.
dotancohen,

1
mystring.Substring (mystring.Length - 4, 4) è uguale a: mystring.Substring (mystring.Length - 4)
Moe Howard

6

È solo questo:

int count = 4;
string sub = mystring.Substring(mystring.Length - count, count);

6

Rispetto ad alcune risposte precedenti, la differenza principale è che questo pezzo di codice prende in considerazione quando la stringa di input è:

  1. Nullo
  2. Più lungo o corrispondente alla lunghezza richiesta
  3. Più corto della lunghezza richiesta.

Ecco qui:

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

    public static string MyLast(this string str, int length)
    {
        if (str == null)
            return null;
        else if (str.Length >= length)
            return str.Substring(str.Length - length, length);
        else
            return str;
    }
}

4

Definizione:

public static string GetLast(string source, int last)
{
     return last >= source.Length ? source : source.Substring(source.Length - last);
}

Uso:

GetLast("string of", 2);

Risultato:

di


3

Questo non fallirà per nessuna stringa di lunghezza.

string mystring = "34234234d124";
string last4 = Regex.Match(mystring, "(?!.{5}).*").Value;
// last4 = "d124"
last4 = Regex.Match("d12", "(?!.{5}).*").Value;
// last4 = "d12"

Questo è probabilmente eccessivo per l'attività a portata di mano, ma se è necessaria un'ulteriore convalida, può eventualmente essere aggiunto all'espressione regolare.

Modifica: penso che questo regex sarebbe più efficiente:

@".{4}\Z"

5
Decisamente eccessivo. Attaccherei con semplici metodi di stringa per questo.
tsells,

La seconda variante non restituisce una stringa di tre lettere quando viene chiamata con un argomento di tre lettere, quindi non equivale alla tua prima versione ingegnosa che utilizza lookahead negativo! :-)
avl_sweden il

3

Usa un generico Last<T>. Funzionerà con QUALSIASI IEnumerable, inclusa la stringa.

public static IEnumerable<T> Last<T>(this IEnumerable<T> enumerable, int nLastElements)
{
    int count = Math.Min(enumerable.Count(), nLastElements);
    for (int i = enumerable.Count() - count; i < enumerable.Count(); i++)
    {
        yield return enumerable.ElementAt(i);
    }
}

E uno specifico per la stringa:

public static string Right(this string str, int nLastElements)
{
    return new string(str.Last(nLastElements).ToArray());
}

1
Wow. Eccessivo. Forse qualcosa come enumerable.Skip (enumerable.Count () - nLastElements)?
Buh Buh,

Non sono d'accordo con @BuhBuh sul fatto che questo sia eccessivo. Ma preferisco "Last" a "Right" come nome. Sono un po 'schizzinoso nel sovraccaricare l'ultimo di IEnumerable <T> esistente. Anch'io sono incline a "Skip".
Probabilmente negabile il

Mi piace questa soluzione. Non semplice ma interessante quando apprendi IEnumerable.
pKarelian il

1

Ho messo insieme alcuni codici modificati da varie fonti che otterranno i risultati desiderati e ne farò molto di più. Ho consentito valori int negativi, valori int che superano la lunghezza della stringa e che l'indice finale sia inferiore all'indice iniziale. In quest'ultimo caso, il metodo restituisce una sottostringa di ordine inverso. Ci sono molti commenti, ma fammi sapere se qualcosa non è chiaro o è semplicemente pazzo. Ci stavo giocando con questo per vedere per cosa potevo usarlo.

    /// <summary>
    /// Returns characters slices from string between two indexes.
    /// 
    /// If start or end are negative, their indexes will be calculated counting 
    /// back from the end of the source string. 
    /// If the end param is less than the start param, the Slice will return a 
    /// substring in reverse order.
    /// 
    /// <param name="source">String the extension method will operate upon.</param>
    /// <param name="startIndex">Starting index, may be negative.</param>
    /// <param name="endIndex">Ending index, may be negative).</param>
    /// </summary>
    public static string Slice(this string source, int startIndex, int endIndex = int.MaxValue)
    {
        // If startIndex or endIndex exceeds the length of the string they will be set 
        // to zero if negative, or source.Length if positive.
        if (source.ExceedsLength(startIndex)) startIndex = startIndex < 0 ? 0 : source.Length;
        if (source.ExceedsLength(endIndex)) endIndex = endIndex < 0 ? 0 : source.Length;

        // Negative values count back from the end of the source string.
        if (startIndex < 0) startIndex = source.Length + startIndex;
        if (endIndex < 0) endIndex = source.Length + endIndex;         

        // Calculate length of characters to slice from string.
        int length = Math.Abs(endIndex - startIndex);
        // If the endIndex is less than the startIndex, return a reversed substring.
        if (endIndex < startIndex) return source.Substring(endIndex, length).Reverse();

        return source.Substring(startIndex, length);
    }

    /// <summary>
    /// Reverses character order in a string.
    /// </summary>
    /// <param name="source"></param>
    /// <returns>string</returns>
    public static string Reverse(this string source)
    {
        char[] charArray = source.ToCharArray();
        Array.Reverse(charArray);
        return new string(charArray);
    }

    /// <summary>
    /// Verifies that the index is within the range of the string source.
    /// </summary>
    /// <param name="source"></param>
    /// <param name="index"></param>
    /// <returns>bool</returns>
    public static bool ExceedsLength(this string source, int index)
    {
        return Math.Abs(index) > source.Length ? true : false;
    }

Quindi, se hai una stringa come "Questo è un metodo di estensione", ecco alcuni esempi e risultati da aspettarti.

var s = "This is an extension method";
// If you want to slice off end characters, just supply a negative startIndex value
// but no endIndex value (or an endIndex value >= to the source string length).
Console.WriteLine(s.Slice(-5));
// Returns "ethod".
Console.WriteLine(s.Slice(-5, 10));
// Results in a startIndex of 22 (counting 5 back from the end).
// Since that is greater than the endIndex of 10, the result is reversed.
// Returns "m noisnetxe"
Console.WriteLine(s.Slice(2, 15));
// Returns "is is an exte"

Spero che questa versione sia utile a qualcuno. Funziona come di consueto se non si utilizzano numeri negativi e fornisce valori predefiniti per i parametri fuori intervallo.


1
string var = "12345678";

if (var.Length >= 4)
{
    var = var.substring(var.Length - 4, 4)
}

// result = "5678"

1

supponendo di volere le stringhe tra una stringa che si trova a 10 caratteri dall'ultimo carattere e che sono necessari solo 3 caratteri.

Diciamo StreamSelected = "rtsp://72.142.0.230:80/SMIL-CHAN-273/4CIF-273.stream"

In quanto sopra, ho bisogno di estrarre quello "273"che userò nella query del database

        //find the length of the string            
        int streamLen=StreamSelected.Length;

        //now remove all characters except the last 10 characters
        string streamLessTen = StreamSelected.Remove(0,(streamLen - 10));   

        //extract the 3 characters using substring starting from index 0
        //show Result is a TextBox (txtStreamSubs) with 
        txtStreamSubs.Text = streamLessTen.Substring(0, 3);

Questa domanda richiede esplicitamente gli ultimi quattro caratteri nella stringa. Sembra che tu stia rispondendo a una domanda diversa relativa all'estrazione di cose dal centro della stringa. Inoltre Substringti consente già di passare un punto iniziale e una lunghezza, quindi non sei sicuro del motivo per cui non lo utilizzeresti piuttosto che utilizzare Removeper rimuovere prima l'inizio.
Chris,

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.