Estrai solo la maggior parte delle n lettere a destra da una stringa


110

Come posso estrarre un substringche è composto dalle sei lettere più a destra da un altro string?

Es: la mia stringa è "PER 343573". Ora voglio solo estrarre "343573".

Come posso fare questo?


È possibile utilizzare il codice sorgente per il metodo VB.NET Right. Dovresti prima convertire in C #: referencesource.microsoft.com/#Microsoft.VisualBasic/… Converti in C # utilizzando converter.telerik.com
Darren Griffith

ma il codice VB si basa sulla funzione di sottostringa c # in strings.sc
Our Man in Bananas

Questo non è davvero un buon modo per farlo, ma se sei in difficoltà, puoi aggiungere un riferimento a Microsoft.VisualBasic.dll e utilizzare il metodo Right. Non è un metodo di estensione. Devi usarlo in questo modo:string endOfString = Strings.Right(wholeString, 6);
Alan McBee - MSFT

Risposte:


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

35
Questo approccio non funziona correttamente se la stringa non è lunga quanto il numero di caratteri richiesti.
Stevehipwell

1
A seconda di cosa vuole esattamente l'OP, si potrebbero anche lanciare espressioni regolari. Se vuole solo il numero alla fine della stringa, questa è sicuramente la soluzione più indolore, soprattutto quando il numero di cifre può variare in qualche aggiornamento software successivo.
Joey

2
@Johannes Rössel - Sono un grande fan delle espressioni regolari (vedi le mie risposte), ma non le consiglierei mai per una situazione semplice come questa. Tutte le risposte che utilizzano un wrapper di funzione sono più adatte alla manutenzione del codice rispetto a un'espressione regolare. Un metodo di estensione (o una funzione standard se .NET 2.0) è la soluzione migliore.
Stevehipwell

@ Stevo3000 - avere una soluzione che genera se la stringa è di lunghezza errata è una soluzione valida. Non l'unica soluzione, ma comunque.
Marc L.

3
@ James - per essere altrettanto pernickity, solo il titolo menzionato "n lettere". La vera domanda posta chiedeva "le sei lettere più a destra" :)
Chris Rogers

69

Scrivi un metodo di estensione per esprimere la Right(n);funzione. La funzione dovrebbe gestire stringhe nulle o vuote che restituiscono una stringa vuota, stringhe più brevi della lunghezza massima che restituiscono la stringa originale e stringhe più lunghe della lunghezza massima che restituiscono la lunghezza massima dei caratteri più a destra.

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

Anche l'indice iniziale non può essere inferiore a 0.
James,

2
@ James - Non sarà come sValue.Length > iMaxLengthprima che venga chiamata una sottostringa!
Stevehipwell

3
Ottima risposta, ma è stato un po 'un doppio tentativo vedere la notazione ungherese nel codice C #.
Jerad Rose

1
@JeradRose - Lavoro in un progetto in cui la base di codice si è evoluta da un'applicazione VB3 (la maggior parte di questa è VB.NET), quindi ci sono alcuni resti.
stevehipwell

4
@ Jalle, VB.NET ha Left, Right e Mid come funzioni di primo livello, oltre a molte altre cose utili che non fanno parte di C #. Non sono sicuro del perché, poiché molti di loro sono funzioni decenti.
ingrediente_15939

40

Probabilmente è più bello usare un metodo di estensione:

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

uso

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

19
Quindi genererebbe una NullReferenceException proprio come se provassi a utilizzare qualsiasi metodo su una stringa nulla ...
James

1
str.Length - lengthpotrebbe essere negativo. Anche il secondo parametro è opzionale. Non c'è bisogno di passare la lunghezza.
iheartcsharp

1
@ JMS10 potrebbe certamente essere, ma questo è più preoccupante per i chiamanti che per il mio. Inoltre, sì, giusto punto, potresti usare l'override che prende solo il singolo parametro qui.
James

str? .Substring (str.Length - length, length);
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
}

Non dovrebbe generare errori, restituisce valori nulli come stringa vuota, restituisce valori di base o tagliati. Usalo come "testx" .Left (4) o str.Right (12);


13

MSDN

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

EDIT: troppo lento ...


9

se non sei sicuro della lunghezza della stringa, ma sei sicuro del conteggio delle parole (sempre 2 parole in questo caso, come "xxx yyyyyy") faresti meglio a usare split.

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

restituisce sempre la seconda parola della stringa.


Sì; supponiamo solo che il testo di OP abbia SEMPRE spazi bianchi; come nel suo esempio :)
Christian

1
Hei Christian :) sappiamo tutti più di un paio di righe di una risposta. Ho appena risposto alla domanda in breve, ovviamente, ci sono molte più cose da considerare nel codice reale.
Mahdi Tahsildari

7

Non è esattamente quello che stai chiedendo, ma solo guardando l'esempio, sembra che stai cercando la sezione numerica della stringa.

Se è sempre così, allora un buon modo per farlo sarebbe usare un'espressione regolare.

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

-1 le espressioni regolari sono un po 'eccessive per qualcosa di simile, specialmente quando ci sono già metodi incorporati per farlo.
James il

1
Non sto discutendo per l'utilizzo di questo metodo se hai davvero bisogno solo degli ultimi 6, ma se il tuo obiettivo è estrarre un numero (come un id) che potrebbe cambiare a 5 o 7 cifre in futuro, questo è un modo migliore.
brividi 42

1
Vecchia risposta, ma +1 per supportare l'uso di espressioni regolari. Soprattutto perché non ci sono (ancora) metodi incorporati nell'implementazione String di .NET per farlo @James. Altrimenti, questa domanda potrebbe non essere mai esistita.
CrazyIvan1974

@ CrazyIvan1974 non sono sicuro del motivo per cui mi hai menzionato nel tuo commento
James

5

Usa questo:

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

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

5

Indovinando le tue esigenze, ma la seguente espressione regolare produrrà solo 6 caratteri alfanumerici prima della fine della stringa e altrimenti non corrisponderà.

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

Questa soluzione non soddisfa ragionevolmente i requisiti vaghi? In caso contrario, spiega il tuo voto negativo.
Wade

5

Poiché stai utilizzando .NET, che viene compilato in MSIL , fai riferimento a Microsoft.VisualBasic e utilizza il Strings.Rightmetodo integrato di Microsoft :

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

Non è necessario creare un metodo di estensione personalizzato o altro lavoro. Il risultato si ottiene con un riferimento e una semplice riga di codice.

Come ulteriori informazioni su questo, l'utilizzo di metodi Visual Basic con C # è stato documentato altrove . Personalmente mi sono imbattuto per primo durante il tentativo di analizzare un file e ho trovato questo thread SO sull'utilizzo della Microsoft.VisualBasic.FileIO.TextFieldParserclasse estremamente utile per l'analisi dei file .csv.


Questo approccio è stato anche dettagliato in un altro thread SO qui: stackoverflow.com/a/15255454/2658159
Aaron Thomas,

Questo è MENTALE! Ma come ragazzo VB, è bello spadroneggiare su CSharpers per una volta!
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"

questo supporta qualsiasi numero di caratteri in str. il codice alternativo non supporta la nullstringa. e, il primo è più veloce e il secondo è più compatto.

preferisco il secondo se si conosce la strbreve stringa contenente. se è lunga la stringa è più adatta.

per esempio

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()); // ""

o

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
Mi piace questa alternativa. Verboso, ma facile da capire e gestisce automaticamente il problema delle stringhe troppo corte.
Andrew Grothe

3

Usa questo:

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


3

Un'altra soluzione che potrebbe non essere menzionata

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

3

Metodi nulli sicuri:

Stringhe più corte della lunghezza massima che restituiscono la stringa originale

Metodo di estensione String Right

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

Metodo di estensione a sinistra della stringa

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

2

Ecco la soluzione che uso ... Controlla che la lunghezza della stringa di input non sia inferiore alla lunghezza richiesta. Le soluzioni che vedo pubblicate sopra non ne tengono conto purtroppo, il che può portare a arresti anomali.

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

Questo è il metodo che utilizzo: mi piace mantenere le cose semplici.

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

1

Solo un pensiero:

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")

Qualcuno ha contrassegnato il tuo post per l'eliminazione e l' ho visto in una coda di revisione . Penso che il tuo post sia stato contrassegnato in modo errato. Le risposte di solo codice non sono di bassa qualità . Tenta di rispondere alla domanda? In caso contrario, bandiera. È tecnicamente errato? Downvote.
Wai Ha Lee

1
Il codice dovrebbe essere accompagnato da una spiegazione scritta su come risolve il problema nell'OP.
Zze

1
Bene, pensavo che la spiegazione scritta nei commenti fosse sufficiente, no?
vldmrrr

0

Senza ricorrere al convertitore di bit e allo spostamento di bit (è necessario essere sicuri della codifica) questo è il metodo più veloce che uso come metodo di estensione "Right".

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.Reverseaccetta un array, non una stringa, e if (myString.length > 6). Errori di sintassi a parte, perché questo dovrebbe essere il metodo più veloce? Sicuramente il solo utilizzo della sottostringa sarebbe un modo migliore, non richiederebbe tutta questa copia di array.
1800 INFORMAZIONI

0

Uso il Min per prevenire le situazioni negative e gestire anche stringhe null

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

l'output è "Word"

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.