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.