Comment obtenir les quatre derniers caractères d'une chaîne en C #?

309

Supposons que j'ai une chaîne:

"34234234d124"

Je veux obtenir les quatre derniers caractères de cette chaîne qui est "d124". Je peux l'utiliser SubString, mais il a besoin de quelques lignes de code, y compris le nom d'une variable.

Est-il possible d'obtenir ce résultat en une seule expression avec C #?

KentZhou
la source
3
Que voulez-vous quand il y a moins de 4 caractères?
agent-j
12
4 > mystring.length ? mystring : mystring.Substring(mystring.length -4);
Jodrell
3
En Python , la solution est simple: "hello world"[-4:]. J'espère qu'une future version de C # le rendra aussi simple.
Colonel Panic
@ColonelPanic, maintenant vous pouvez avec C # 8.0: "hello world"[^4..]:-)
Frode Evensen

Réponses:

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

Si vous êtes certain que la longueur de votre chaîne est d'au moins 4, elle est encore plus courte:

mystring.Substring(mystring.Length - 4);
Armen Tsirunyan
la source
13
De plus, il échouera si sa mystringlongueur est inférieure à 4 caractères.
George Duckett
3
+1 parce que je pense que le vôtre est légèrement plus lisible que celui de @ dtb
George Duckett
Prendre quelques lignes de code (que l'OP connaissait déjà) et les entasser sur une seule ligne n'est pas vraiment la même chose qu'une expression.
Buh Buh
1
Je l'aime. Simple et élégant et prend le maximum, donc si votre chaîne est inférieure à 0, vous n'obtiendrez pas d'exception d'index.
Bretticus
+1 simple et au point, couvre toutes les bases. La méthode d'extension proposée par Stecya est également bonne, mais un peu trop tuer si vous ne le faites qu'une seule fois.
Morvael
205

Vous pouvez utiliser une méthode d'extension :

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

Et puis appelez:

string mystring = "34234234d124";
string res = mystring.GetLast(4);
Stecya
la source
11
J'aime ça, mais je l'appellerais probablement Last (). Après tout, Substring () n'est pas GetSubstring ().
Buh Buh
21
Peut-être l'appeler Tail () car Last se heurte à l'extension Linq Last ().
Craig Curtis
5
+1 pour l'avoir "beaucoup plus longue que 1 ligne". C'est tellement ennuyeux de voir du code illisible à cause des économies de ligne.
Fabio Milheiro
2
Ou appelez-le Right () pour la cohérence avec VisualBasic selon la réponse de @RJ Programmer (je ne veux pas ajouter un autre assembly juste pour une fonction).
christutty
3
J'adore cette solution.
Luke
46

Tout ce que tu dois faire est..

String result = mystring.Substring(mystring.Length - 4);
l'étoile
la source
2
Pas si vous voulez qu'une exception soit levée si la longueur est inférieure à 4 ...
Milos Mrdovic
45

Ok, donc je vois que c'est un vieux post, mais pourquoi réécrivons-nous du code qui est déjà fourni dans le framework?

Je suggérerais que vous ajoutiez une référence à la DLL du framework "Microsoft.VisualBasic"

using Microsoft.VisualBasic;
//...

string value = Strings.Right("34234234d124", 4);
Programmeur RJ
la source
8
Bel exemple de temps pour utiliser la fonctionnalité VB
Brian White
3
Je t'aime. La plupart de mon expérience de programmation est VB, donc découvrir que je peux utiliser toutes ces fonctions que je connais si bien est génial
Ben Strombeck
6
Je ne peux jamais comprendre si l'utilisation de MS.VB est une bonne idée - pourquoi est-elle shuntée dans l' VisualBasicespace de noms? TextFieldParserest un autre exemple. Pourquoi ces utilitaires sont-ils si étrangement pris en compte?
ruffin
6
Je pense que cela devrait être la réponse acceptée. Pourquoi réinventer la roue?
Zack
2
@Bomboca: Nous pouvons être assurés que cela continuera tant que Microsoft continuera à prendre en charge Visual Basic. Il est inclus dans la version 4.6 et je ne trouve rien d'explicite ou implicite de la part de MS qu'ils envisagent d'arrêter de prendre en charge VB.Net en tant que langage de développement.
Programmeur RJ
30
string mystring = "34234234d124";
mystring = mystring.Substring(mystring.Length-4)
Cem
la source
26

L'utilisation de Substring est en fait assez courte et lisible:

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

Voici une autre alternative qui ne devrait pas trop mal fonctionner (à cause d'une exécution différée ):

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

Bien qu'une méthode d'extension à cet effet mystring.Last(4)soit clairement la solution la plus propre, bien qu'un peu plus de travail.

Andre Luus
la source
1
@BrianWhite Les gens sont grincheux après le nouvel an?
Konrad Viltersten
1
Belle solution. je l'aime. Mais vous avez oublié d'autres inverses pour obtenir la chaîne correcte. Doit être: nouvelle chaîne (mystring.Reverse (). Take (4) .Reverse (). ToArray ());
Yuri Morales
Aah oui, vous avez raison - mon compilateur mental n'a pas pensé aussi loin. Malheureusement, cela semble encore pire! :)
Andre Luus
1
En raison de ToArray, il n'y a pas d'exécution différée
1
Je ne pense pas que vous compreniez, @ BjörnAliGöransson, mon point était que le Reverse().Take(4).Reverse()chacun n'énumère pas la chaîne entière, cela ne se produit qu'au dernier ToArrayappel. S'il n'existait pas une exécution différée, cela se traduirait par Reverse().ToArray().Take(4).ToArray().Reverse().ToArray(). Ceci, bien sûr, suppose que ces extensions sont du type différé - ce que je n'ai pas vérifié. Les constructeurs String n'acceptent pas IEnumerable, vous devez donc l'énumérer dans un tableau à ce stade.
Andre Luus
17

Vous pouvez simplement utiliser la Substringméthode de C #. Par exemple.

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

Il renverra le résultat 0000.

Amit Kumawat
la source
7
Cela a été répondu comme 28 fois et vous l'avez ajouté à nouveau? Et pourquoi utiliser la surcharge à deux paramètres au lieu de celle qui ne reçoit que startIndex?
Andrew
Exactement la réponse dont j'avais besoin. Merci pour le partage @Amit Kumawat.
Daryl
12

Une solution simple serait:

string mystring = "34234234d124";
string last4 = mystring.Substring(mystring.Length - 4, 4);
Anees Deen
la source
7
mystring = mystring.Length > 4 ? mystring.Substring(mystring.Length - 4, 4) : mystring;
Michael Burggraf
la source
Bien, mais je pense que tu =ne voulais pas =+.
dotancohen
1
mystring.Substring (mystring.Length - 4, 4) est le même que: mystring.Substring (mystring.Length - 4)
Moe Howard
6

C'est juste ça:

int count = 4;
string sub = mystring.Substring(mystring.Length - count, count);
Daniel DiPaolo
la source
6

Par rapport à certaines réponses précédentes, la principale différence est que ce morceau de code prend en considération lorsque la chaîne d'entrée est:

  1. Nul
  2. Plus long ou correspondant à la longueur demandée
  3. Plus courte que la longueur demandée.

C'est ici:

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;
    }
}
Marcelo Finki
la source
4

Définition:

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

Usage:

GetLast("string of", 2);

Résultat:

de

Erçin Dedeoğlu
la source
3

Cela n'échouera pour aucune chaîne de longueur.

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

C'est probablement exagéré pour la tâche à accomplir, mais s'il doit y avoir une validation supplémentaire, elle peut éventuellement être ajoutée à l'expression régulière.

Edit: je pense que ce regex serait plus efficace:

@".{4}\Z"
agent-j
la source
5
Certainement exagéré. Je m'en tiendrai à des méthodes de chaîne simples pour cela.
tsells
La deuxième variante ne retourne pas une chaîne de trois lettres lorsqu'elle est appelée avec un argument de trois lettres, elle n'est donc pas équivalente à votre première version ingénieuse utilisant une anticipation négative! :-)
avl_sweden
3

Utilisez un générique Last<T>. Cela fonctionnera avec TOUT IEnumerable, y compris la chaîne.

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

Et un spécifique pour la chaîne:

public static string Right(this string str, int nLastElements)
{
    return new string(str.Last(nLastElements).ToArray());
}
Adriano Carneiro
la source
1
Sensationnel. Trop fort. Peut-être quelque chose comme enumerable.Skip (enumerable.Count () - nLastElements)?
Buh Buh
Je ne suis pas d'accord avec @BuhBuh sur le fait que cela soit exagéré. Mais je préfère "Last" à "Right" comme nom. Je suis un peu mal à l'aise de surcharger le dernier existant de IEnumerable <T>. Je penche également vers "Skip", aussi.
Plausably Deniable
J'aime cette solution. Pas simple mais intéressant quand on apprend IEnumerable.
pKarelian
1

J'ai jeté ensemble du code modifié à partir de diverses sources qui obtiendra les résultats que vous souhaitez, et en faire bien plus encore. J'ai autorisé des valeurs int négatives, des valeurs int qui dépassent la longueur de la chaîne et un index de fin inférieur à l'index de début. Dans ce dernier cas, la méthode renvoie une sous-chaîne d'ordre inverse. Il y a beaucoup de commentaires, mais faites-moi savoir si quelque chose n'est pas clair ou tout simplement fou. Je jouais avec ça pour voir à quoi je pourrais l'utiliser.

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

Donc, si vous avez une chaîne comme "Ceci est une méthode d'extension", voici quelques exemples et résultats à attendre.

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"

J'espère que cette version est utile à quelqu'un. Il fonctionne comme d'habitude si vous n'utilisez pas de nombres négatifs et fournit des paramètres par défaut pour les paramètres hors plage.

irlandais
la source
1
string var = "12345678";

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

// result = "5678"
Eidan
la source
1

en supposant que vous vouliez les chaînes entre une chaîne qui se trouve à 10 caractères du dernier caractère et que vous n'avez besoin que de 3 caractères.

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

Dans ce qui précède, je dois extraire le "273"que j'utiliserai dans la requête de base de données

        //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);
Shinn_33
la source
Cette question demande explicitement les quatre derniers caractères de la chaîne. Vous semblez répondre à une question différente liée à l'extraction de choses du milieu de la chaîne. AussiSubstring permet déjà de saisir un point de départ et une longueur, donc vous ne savez pas pourquoi vous n'utiliseriez pas cela plutôt que Removede supprimer le début en premier.
Chris
0

Mise à jour 2020 : C # 8.0 rend enfin cela facile:

> "C# 8.0 finally makes this easy"[^4..]
"easy"

Vous pouvez également découper des tableaux de la même manière, voir Indices et plages .

Colonel Panic
la source