Como obtenho os últimos quatro caracteres de uma string em C #?

309

Suponha que eu tenha uma string:

"34234234d124"

Eu quero obter os últimos quatro caracteres dessa string, que é "d124". Eu posso usar SubString, mas ele precisa de algumas linhas de código, incluindo nomear uma variável.

É possível obter esse resultado em uma expressão com c #?

KentZhou
fonte
3
O que você deseja quando há menos de 4 caracteres?
agent-j
12
4 > mystring.length ? mystring : mystring.Substring(mystring.length -4);
Jodrell
3
Em Python, a solução é simples: "hello world"[-4:]. Espero que uma versão futura do C # facilite isso.
Coronel Panic
@ColonelPanic, agora você pode com o C # 8.0: "hello world"[^4..]:-)
Frode Evensen

Respostas:

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

Se você tem certeza de que o comprimento da sua string é pelo menos 4, é ainda mais curto:

mystring.Substring(mystring.Length - 4);
Armen Tsirunyan
fonte
13
Além disso, ele falhará se mystringtiver menos de 4 caracteres.
precisa
3
+1 porque eu acho que o seu é um pouco mais legível do que @ dtb de
George Duckett
Pegar algumas linhas de código (que o OP já sabia) e colocá-las em uma linha não é a mesma coisa que uma expressão.
usar o seguinte
1
Eu gosto disso. Simples e elegante e leva o máximo, portanto, se sua string for menor que 0, você não receberá uma exceção fora do índice.
Bretticus 13/03/2013
+1 simples e direto ao ponto, abrange todas as bases. O método de extensão proposto por Stecya também é bom, mas um pouco exagerado se você estiver fazendo apenas uma vez.
Morvael 11/03/14
205

Você pode usar um método de extensão :

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 depois chame:

string mystring = "34234234d124";
string res = mystring.GetLast(4);
Stecya
fonte
11
Eu gosto disso, mas provavelmente chamaria Last (). Afinal, Substring () não é GetSubstring ().
usar o seguinte
21
Talvez chame-o de Tail (), já que o Last entra em conflito com o Linq Extension Last ().
Craig Curtis
5
+1 por torná-lo "muito maior que 1 linha". É tão irritante ver código ilegível por causa da economia de linha.
Fabio Milheiro
2
Ou chame-o Right () para obter consistência com o VisualBasic conforme a resposta do @RJ Programmer (eu não quero adicionar outro assembly apenas para uma função).
christutty
3
Eu amo essa solução.
Lucas
46

Tudo o que tem a fazer é..

String result = mystring.Substring(mystring.Length - 4);
a estrela
fonte
2
Não, se você quer uma exceção para ser acionada se o comprimento é inferior a 4 ...
Milos Mrdovic
45

Ok, então vejo que esta é uma postagem antiga, mas por que estamos reescrevendo o código que já é fornecido na estrutura?

Sugiro que você adicione uma referência à DLL de estrutura "Microsoft.VisualBasic"

using Microsoft.VisualBasic;
//...

string value = Strings.Right("34234234d124", 4);
Programador RJ
fonte
8
Bom exemplo de um tempo para usar a funcionalidade VB
Brian White
3
Eu te amo. A maioria da minha experiência em programação é VB, então descobrir que eu posso usar todas essas funções que eu sou tão familiarizado com é incrível
Ben Strombeck
6
Eu nunca consigo descobrir se estou usando o MS.VB uma boa idéia - por que ele é desviado para o VisualBasicespaço para nome? TextFieldParseré outro exemplo. Por que esses utilitários são fatorados de maneira tão estranha?
Ruffin
6
Eu sinto que essa deve ser a resposta aceita. Por que reinventar a roda?
Zack
2
@Bomboca: Podemos ter certeza de que continuará enquanto a Microsoft continuar a oferecer suporte ao Visual Basic. Ele está incluído na versão 4.6 e não consigo encontrar nada explícito ou implícito do MS que eles planejem parar de oferecer suporte ao VB.Net como uma linguagem de desenvolvimento.
RJ Programmer
30
string mystring = "34234234d124";
mystring = mystring.Substring(mystring.Length-4)
Cem
fonte
26

Usar Substring é realmente bastante curto e legível:

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

Aqui está outra alternativa que não deve ter um desempenho muito ruim (devido à execução adiada ):

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

Embora um método de extensão para esse fim mystring.Last(4)seja claramente a solução mais limpa, ainda que um pouco mais trabalhoso.

Andre Luus
fonte
1
@BrianWhite As pessoas estão irritadas depois do ano novo?
Konrad Viltersten
1
Ótima solução. eu gosto disso. Mas você esqueceu outro Reverse para obter a string correta. Deve ser: new string (mystring.Reverse (). Take (4) .Reverse (). ToArray ());
Yuri Morales
Aah sim, você está correto - meu compilador mental não chegou tão longe. Infelizmente isso faz parecer ainda pior! :)
Andre Luus
1
Por causa de ToArray não há nenhuma adiada execução
1
Eu não acho que você entenda, @ BjörnAliGöransson, meu ponto é que Reverse().Take(4).Reverse()cada um não enumera toda a string, isso só acontece na ToArraychamada final . Se não houvesse algo como execução adiada, seria traduzido para Reverse().ToArray().Take(4).ToArray().Reverse().ToArray(). Obviamente, isso pressupõe que essas extensões sejam do tipo adiado - que eu não verifiquei. Os construtores String não aceitam IEnumerable, portanto, você deve enumerá-lo em uma matriz nesse momento.
Andre Luus 19/07/16
17

Você pode simplesmente usar o Substringmétodo de c #. Por ex.

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

Retornará o resultado 0000.

Amit Kumawat
fonte
7
Isso foi respondido 28 vezes e você o adicionou novamente? E por que usar a sobrecarga de dois parâmetros em vez da que recebe apenas startIndex?
Andrew
O que você precisa saber para começar o dia bem-informado
Daryl
12

Uma solução simples seria:

string mystring = "34234234d124";
string last4 = mystring.Substring(mystring.Length - 4, 4);
Anees Deen
fonte
7
mystring = mystring.Length > 4 ? mystring.Substring(mystring.Length - 4, 4) : mystring;
Michael Burggraf
fonte
Legal, mas acho que você =não quis dizer =+.
dotancohen 17/07/12
1
mystring.Substring (mystring.Length - 4, 4) é o mesmo que: mystring.Substring (mystring.Length - 4)
Moe Howard
6

É apenas isso:

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

Comparado a algumas respostas anteriores, a principal diferença é que esse trecho de código leva em consideração quando a sequência de entrada é:

  1. Nulo
  2. Maior ou igual ao comprimento solicitado
  3. Menor que o comprimento solicitado.

Aqui está:

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
fonte
4

Definição:

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

Uso:

GetLast("string of", 2);

Resultado:

do

Erçin Dedeoğlu
fonte
3

Isso não falhará em nenhuma sequência de comprimento.

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

Provavelmente, isso é um exagero para a tarefa em questão, mas, se houver necessidade de validação adicional, ela poderá ser adicionada à expressão regular.

Edit: Eu acho que este regex seria mais eficiente:

@".{4}\Z"
agent-j
fonte
5
Definitivamente um exagero. Eu ficaria com métodos simples de string para isso.
tsells 16/01
A segunda variante não retorna uma sequência de três letras quando chamada com um argumento de três letras; portanto, não é equivalente à sua primeira versão engenhosa usando lookahead negativo! :-)
avl_sweden
3

Use um genérico Last<T>. Isso funcionará com QUALQUER IEnumerable, incluindo string.

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 um específico para string:

public static string Right(this string str, int nLastElements)
{
    return new string(str.Last(nLastElements).ToArray());
}
Adriano Carneiro
fonte
1
Uau. Exagero. Talvez algo como enumerable.Skip (enumerable.Count () - nLastElements)?
Buh Buh
Discordo de @BuhBuh sobre esse exagero. Mas eu prefiro "Last" a "Right" como um nome. Eu sou um pouco sensível sobre sobrecarregar o Last of IEnumerable <T> existente. Também estou inclinado a "pular".
Plausibly Deniable
Eu gosto desta solução. Não é simples, mas interessante ao aprender IEnumerable.
PKarelian
1

Juntei alguns códigos modificados de várias fontes que obterão os resultados desejados e farão muito mais. Eu permiti valores int negativos, valores int que excedem o comprimento da string e que o índice final seja menor que o índice inicial. Nesse último caso, o método retorna uma substring de ordem inversa. Há muitos comentários, mas deixe-me saber se algo não está claro ou é apenas louco. Eu estava brincando com isso para ver para que tudo o que eu poderia usar.

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

Portanto, se você tiver uma string como "Este é um método de extensão", aqui estão alguns exemplos e resultados esperados.

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"

Espero que esta versão seja útil para alguém. Funciona da mesma maneira que o normal, se você não usa números negativos, e fornece padrões para parâmetros fora de alcance.

irlandês
fonte
1
string var = "12345678";

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

// result = "5678"
Eidan
fonte
1

supondo que você desejasse as seqüências entre uma sequência que está localizada a 10 caracteres do último caractere e você precisa de apenas 3 caracteres.

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

Acima, preciso extrair o "273"que utilizarei na consulta ao banco de dados

        //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
fonte
Esta pergunta solicita explicitamente os quatro últimos caracteres da string. Você parece estar respondendo a uma pergunta diferente relacionada à extração de coisas do meio da string. Também Substringjá permite que você passe em um ponto inicial e comprimento, então não saiba por que você não usaria isso em vez de usar Removepara remover o início primeiro.
Chris
0

A atualização 2020 : C # 8.0 finalmente facilita isso:

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

Você também pode dividir matrizes da mesma maneira, consulte Índices e intervalos .

Coronel Panic
fonte