Extraire uniquement la plupart des n lettres à droite d'une chaîne


110

Comment puis-je extraire un substringqui est composé des six lettres les plus à droite d'une autre string?

Ex: ma chaîne est "PER 343573". Maintenant, je veux extraire uniquement "343573".

Comment puis-je faire ceci?


Vous pouvez utiliser le code source de la méthode VB.NET Right. Vous devez d'abord convertir en C #: referencesource.microsoft.com/#Microsoft.VisualBasic/... Convertir en C # à l'aide de converter.telerik.com
Darren Griffith

mais le code VB repose sur la fonction c # Substring dans strings.sc
Our Man in Bananas

Ce n'est pas vraiment une très bonne façon de le faire, mais si vous êtes dans un pincement, vous pouvez ajouter une référence à Microsoft.VisualBasic.dll et utiliser la méthode Right. Ce n'est pas une méthode d'extension. Vous devez l'utiliser comme ceci:string endOfString = Strings.Right(wholeString, 6);
Alan McBee - MSFT

Réponses:


156
string SubString = MyString.Substring(MyString.Length-6);

35
Cette approche ne fonctionne pas correctement si la chaîne n'est pas aussi longue que le nombre de caractères requis.
stevehipwell

1
En fonction de ce que veut exactement l'OP, on peut également lancer des expressions régulières. S'il ne veut que le nombre à la fin de la chaîne, c'est certainement la solution la plus indolore, surtout lorsque le nombre de chiffres peut varier lors d'une mise à niveau logicielle ultérieure.
Joey

2
@Johannes Rössel - Je suis un grand fan des expressions régulières (voir mes réponses), mais je ne les recommanderais jamais pour une situation simple comme celle-ci. Toutes les réponses qui utilisent un wrapper de fonction sont mieux adaptées à la maintenance du code qu'une expression régulière. Une méthode d'extension (ou une fonction standard si .NET 2.0) est la meilleure solution.
stevehipwell

@ Stevo3000 - avoir une solution qui lance si la chaîne est de la mauvaise longueur est une solution valide. Pas la seule solution, mais quand même.
Marc L.

3
@James - pour être tout aussi pernickity, seul le titre mentionnait "n lettres". La vraie question posée demandait "les six lettres les plus à droite" :)
Chris Rogers

69

Écrivez une méthode d'extension pour exprimer la Right(n);fonction. La fonction doit traiter des chaînes nulles ou vides renvoyant une chaîne vide, des chaînes plus courtes que la longueur maximale renvoyant la chaîne d'origine et des chaînes plus longues que la longueur maximale renvoyant la longueur maximale des caractères les plus à droite.

public static string Right(this string sValue, int iMaxLength)
{
  //Check if the value is valid
  if (string.IsNullOrEmpty(sValue))
  {
    //Set valid empty string as string could be null
    sValue = string.Empty;
  }
  else if (sValue.Length > iMaxLength)
  {
    //Make the string no longer than the max length
    sValue = sValue.Substring(sValue.Length - iMaxLength, iMaxLength);
  }

  //Return the string
  return sValue;
}

L'index de départ ne peut pas non plus être inférieur à 0.
James

2
@James - Ce ne sera pas comme sValue.Length > iMaxLengthavant l'appel d'une sous-chaîne!
stevehipwell

3
Excellente réponse, mais c'était un peu une double prise pour voir la notation hongroise en code C #.
Jerad Rose

1
@JeradRose - Je travaille dans un projet où la base de code a évolué à partir d'une application VB3 (la plupart de ceci est VB.NET) donc il y a quelques restes.
stevehipwell

4
@Jalle, VB.NET a Left, Right et Mid comme fonctions de niveau supérieur, ainsi que de nombreuses autres choses utiles qui ne font pas partie de C #. Je ne sais pas pourquoi, car beaucoup d'entre elles sont des fonctions décentes.
ingrédient_15939

40

Probablement plus agréable d'utiliser une méthode d'extension:

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

Usage

string myStr = "PER 343573";
string subStr = myStr.Right(6);

19
Ensuite, il lèverait une NullReferenceException comme si vous essayiez d'utiliser n'importe quelle méthode sur une chaîne nulle ...
James

1
str.Length - lengthpourrait être négatif. Le deuxième paramètre est également facultatif. Pas besoin de passer la longueur.
iheartcsharp

1
@ JMS10 cela pourrait certainement être, mais c'est plus le problème des appelants que le mien. De plus, oui, justement, vous pouvez utiliser le remplacement qui ne prend que le paramètre unique ici.
James

str? .Substring (str.Length - longueur, longueur);
Ludwo

26
using System;

public static class DataTypeExtensions
{
    #region Methods

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

    public static string Right(this string str, int length)
    {
        str = (str ?? string.Empty);
        return (str.Length >= length)
            ? str.Substring(str.Length - length, length)
            : str;
    }

    #endregion
}

Ne devrait pas faire d'erreur, renvoie des valeurs nulles sous forme de chaîne vide, renvoie des valeurs réduites ou de base. Utilisez-le comme "testx" .Left (4) ou str.Right (12);


13

MSDN

String mystr = "PER 343573";
String number = mystr.Substring(mystr.Length-6);

EDIT: trop lent ...


9

si vous n'êtes pas sûr de la longueur de votre chaîne, mais que vous êtes sûr que les mots comptent (toujours 2 mots dans ce cas, comme «xxx yyyyyy»), vous feriez mieux d'utiliser split.

string Result = "PER 343573".Split(" ")[1];

cela renvoie toujours le deuxième mot de votre chaîne.


Oui; Supposons simplement que le texte de OP ait TOUJOURS des espaces blancs; comme dans son exemple :)
Christian

1
Hei Christian :) nous en savons tous plus que quelques lignes de réponse. Je viens de répondre à la question brièvement, bien sûr, il y a beaucoup plus de choses à considérer dans le vrai code.
Mahdi Tahsildari le

7

Ce n'est pas exactement ce que vous demandez, mais en regardant simplement l'exemple, il semble que vous recherchez la section numérique de la chaîne.

Si c'est toujours le cas, une bonne façon de le faire serait d'utiliser une expression régulière.

var regex= new Regex("\n+");
string numberString = regex.Match(page).Value;

-1 les expressions régulières sont un peu exagérées pour quelque chose comme ça, surtout quand il existe déjà des méthodes intégrées pour le faire.
James

1
Je ne suis pas en faveur de l'utilisation de cette méthode si vous n'avez vraiment besoin que des 6 derniers, mais si votre objectif est d'extraire un nombre (tel qu'un identifiant) qui pourrait changer en 5 ou 7 chiffres à un moment donné dans le futur, ceci est un meilleur moyen.
frissons42

1
Ancienne réponse, mais +1 pour prendre en charge l'utilisation d'expressions régulières. D'autant qu'il n'y a (toujours) aucune méthode intégrée dans l'implémentation String de .NET pour faire cela @James. Sinon, cette question n'a peut-être jamais existé.
CrazyIvan1974

@ CrazyIvan1974 ne sais pas pourquoi vous m'avez mentionné dans votre commentaire
James

5

Utilisez ceci:

String text = "PER 343573";
String numbers = text;
if (text.Length > 6)
{
    numbers = text.Substring(text.Length - 6);
}

text? .Substring (text.Length - 6)
Ludwo

5

Deviner à vos besoins, mais l'expression régulière suivante ne donnera que 6 alphanumériques avant la fin de la chaîne et aucune correspondance dans le cas contraire.

string result = Regex.Match("PER 343573", @"[a-zA-Z\d]{6}$").Value;

Cette solution ne répond-elle pas raisonnablement aux vagues exigences? Sinon, veuillez expliquer votre vote négatif.
Wade

5

Puisque vous utilisez .NET, qui se compile tous vers MSIL , référencez simplement Microsoft.VisualBasic et utilisez la Strings.Rightméthode intégrée de Microsoft :

using Microsoft.VisualBasic;
...
string input = "PER 343573";
string output = Strings.Right(input, 6);

Pas besoin de créer une méthode d'extension personnalisée ou autre travail. Le résultat est obtenu avec une référence et une simple ligne de code.

Pour plus d'informations à ce sujet, l'utilisation de méthodes Visual Basic avec C # a été documentée ailleurs . Personnellement, je suis tombé dessus en essayant d'analyser un fichier, et j'ai trouvé que ce fil SO sur l'utilisation de la Microsoft.VisualBasic.FileIO.TextFieldParserclasse était extrêmement utile pour analyser les fichiers .csv.


Cette approche a également été détaillée dans un autre fil de discussion SO ici: stackoverflow.com/a/15255454/2658159
Aaron Thomas

C'est MENTAL! Mais en tant que gars de VB, c'est bien de le dominer sur les CSharpers pour une fois!
SteveCinq

5
var str = "PER 343573";
var right6 = string.IsNullOrWhiteSpace(str) ? string.Empty 
             : str.Length < 6 ? str 
             : str.Substring(str.Length - 6); // "343573"
// alternative
var alt_right6 = new string(str.Reverse().Take(6).Reverse().ToArray()); // "343573"

cela prend en charge n'importe quel nombre de caractères dans le str. le code alternatif ne prend pas en charge la nullchaîne. et, le premier est plus rapide et le second est plus compact.

je préfère le second si je connais la strchaîne courte contenant. si c'est une longue chaîne, la première est plus appropriée.

par exemple

var str = "";
var right6 = string.IsNullOrWhiteSpace(str) ? string.Empty 
             : str.Length < 6 ? str 
             : str.Substring(str.Length - 6); // ""
// alternative
var alt_right6 = new string(str.Reverse().Take(6).Reverse().ToArray()); // ""

ou

var str = "123";
var right6 = string.IsNullOrWhiteSpace(str) ? string.Empty 
             : str.Length < 6 ? str 
             : str.Substring(str.Length - 6); // "123"
// alternative
var alt_right6 = new string(str.Reverse().Take(6).Reverse().ToArray()); // "123"

1
J'aime cette alternative. Verbose, mais facile à comprendre et gère automatiquement le problème des chaînes trop courtes.
Andrew Grothe

3

Utilisez ceci:

string mystr = "PER 343573"; int number = Convert.ToInt32(mystr.Replace("PER ",""));


3

Une autre solution qui peut ne pas être mentionnée

S.Substring(S.Length < 6 ? 0 : S.Length - 6)

3

Méthodes Null Safe:

Chaînes plus courtes que la longueur maximale renvoyant la chaîne d'origine

Méthode d'extension de la chaîne droite

public static string Right(this string input, int count) =>
    String.Join("", (input + "").ToCharArray().Reverse().Take(count).Reverse());

Méthode d'extension de chaîne à gauche

public static string Left(this string input, int count) =>
    String.Join("", (input + "").ToCharArray().Take(count));

2

Voici la solution que j'utilise ... Elle vérifie que la longueur de la chaîne d'entrée n'est pas inférieure à la longueur demandée. Les solutions que je vois publiées ci-dessus n'en tiennent malheureusement pas compte - ce qui peut entraîner des plantages.

    /// <summary>
    /// Gets the last x-<paramref name="amount"/> of characters from the given string.
    /// If the given string's length is smaller than the requested <see cref="amount"/> the full string is returned.
    /// If the given <paramref name="amount"/> is negative, an empty string will be returned.
    /// </summary>
    /// <param name="string">The string from which to extract the last x-<paramref name="amount"/> of characters.</param>
    /// <param name="amount">The amount of characters to return.</param>
    /// <returns>The last x-<paramref name="amount"/> of characters from the given string.</returns>
    public static string GetLast(this string @string, int amount)
    {
        if (@string == null) {
            return @string;
        }

        if (amount < 0) {
            return String.Empty;
        }

        if (amount >= @string.Length) {
            return @string;
        } else {
            return @string.Substring(@string.Length - amount);
        }
    }

2

C'est la méthode que j'utilise: j'aime garder les choses simples.

private string TakeLast(string input, int num)
{
    if (num > input.Length)
    {
        num = input.Length;
    }
    return input.Substring(input.Length - num);
}

1

Juste une pensée:

public static string Right(this string @this, int length) {
    return @this.Substring(Math.Max(@this.Length - length, 0));
}

1
//s - your string
//n - maximum number of right characters to take at the end of string
(new Regex("^.*?(.{1,n})$")).Replace(s,"$1")

Quelqu'un a signalé votre message pour suppression et je l'ai vu dans une file d'attente d'examen . Je pense que votre message n'a pas été correctement signalé. Les réponses basées uniquement sur le code ne sont pas de mauvaise qualité . Tente-t-il de répondre à la question? Sinon, signalez. Est-ce techniquement incorrect? Voter contre.
Wai Ha Lee

1
Le code doit être accompagné d'une explication écrite expliquant comment il résout le problème dans l'OP.
Zze

1
Eh bien, je pensais qu'une explication écrite dans les commentaires était suffisante, non?
vldmrrr

0

Sans recourir au convertisseur de bits et au décalage de bits (il faut être sûr de l'encodage), c'est la méthode la plus rapide que j'utilise comme méthode d'extension «Droite».

string myString = "123456789123456789";

if (myString > 6)
{

        char[] cString = myString.ToCharArray();
        Array.Reverse(myString);
        Array.Resize(ref myString, 6);
        Array.Reverse(myString);
        string val = new string(myString);
}

2
Array.Reverseprend un tableau, pas une chaîne, et if (myString.length > 6). Mis à part les erreurs de syntaxe, pourquoi serait-ce la méthode la plus rapide? Utiliser simplement une sous-chaîne serait certainement un meilleur moyen, cela ne nécessiterait pas toute cette copie de tableaux.
1800 INFORMATION

0

J'utilise le Min pour éviter les situations négatives et gère également les chaînes nulles

// <summary>
    /// Returns a string containing a specified number of characters from the right side of a string.
    /// </summary>
    public static string Right(this string value, int length)
    {
        string result = value;
        if (value != null)
            result = value.Substring(0, Math.Min(value.Length, length));
        return result;
    }

0
using Microsoft.visualBasic;

 public class test{
  public void main(){
   string randomString = "Random Word";
   print (Strings.right(randomString,4));
  }
 }

la sortie est "Word"

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.