Extraia apenas a maioria das n letras corretas de uma string

110

Como posso extrair um substringcomposto das seis letras mais à direita de outrostring ?

Ex: minha string é "PER 343573". Agora quero extrair apenas "343573".

Como posso fazer isso?

Shyju
fonte
Você pode usar o código-fonte para o método VB.NET Right. Você precisaria converter para C # primeiro: referênciasource.microsoft.com/ # Microsoft.VisualBasic/… Converter para C # usando converter.telerik.com
Darren Griffith
mas o código VB depende da função c # Substring em strings.sc
Our Man in Bananas
Essa não é uma maneira muito boa de fazer isso, mas se você estiver em apuros, pode adicionar uma referência a Microsoft.VisualBasic.dll e usar o método correto. Não é um método de extensão. Você deve usá-lo assim:string endOfString = Strings.Right(wholeString, 6);
Alan McBee - MSFT

Respostas:

156
string SubString = MyString.Substring(MyString.Length-6);
Vilx-
fonte
35
Esta abordagem não funciona corretamente se a string não for tão longa quanto o número de caracteres necessários.
stevehipwell
1
Dependendo do que exatamente o OP deseja, pode-se também lançar expressões regulares nisso. Se ele quiser apenas o número no final da string, essa é definitivamente a solução mais fácil, especialmente quando o número de dígitos pode variar em alguma atualização de software posterior.
Joey
2
@Johannes Rössel - Sou um grande fã de expressões regulares (veja minhas respostas), mas nunca as recomendaria para uma situação simples como essa. Qualquer uma das respostas que usam um wrapper de função é mais adequada para manutenção de código do que uma expressão regular. Um método de extensão (ou função padrão se .NET 2.0) é a melhor solução.
stevehipwell
@ Stevo3000 - ter uma solução que lança se a string tiver o comprimento errado é uma solução válida. Não é a única solução, mas ainda assim.
Marc L.
3
@James - para ser tão perverso, apenas o título mencionava "n letras". A questão real colocada era "as seis letras mais à direita" :)
Chris Rogers
69

Escreva um método de extensão para expressar a Right(n);função. A função deve lidar com strings nulas ou vazias retornando uma string vazia, strings menores que o comprimento máximo retornando a string original e strings maiores que o comprimento máximo retornando o comprimento máximo dos caracteres mais à direita.

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;
}
Stevehipwell
fonte
O índice inicial não pode ser menor que 0 também.
James
2
@James - Não será como sValue.Length > iMaxLengthantes de uma substring ser chamada!
stevehipwell
3
Ótima resposta, mas foi um pouco confuso ver a notação húngara no código C #.
Jerad Rose
1
@JeradRose - Eu trabalho em um projeto em que o código base evoluiu de um aplicativo VB3 (a maior parte dele é VB.NET), então há alguns resquícios.
stevehipwell
4
@Jalle, VB.NET tem Left, Right e Mid como funções de nível superior, além de muitas outras coisas úteis que não fazem parte do C #. Não sei por que, pois muitos deles são funções decentes.
ingrediente_15939
40

Provavelmente melhor usar um método de extensão:

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);
James
fonte
19
Em seguida, ele lançaria uma NullReferenceException, exatamente como faria se você tentasse usar qualquer método em uma string nula ...
James
1
str.Length - lengthpode ser negativo. Além disso, o segundo parâmetro é opcional. Não há necessidade de passar o comprimento.
iheartcsharp
1
@ JMS10 certamente poderia ser, mas essa é mais a preocupação dos chamadores do que minha. Além disso, sim, justo ponto, você poderia usar a substituição que usa apenas o único parâmetro aqui.
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
}

Não deve dar erro, retorna nulos como string vazia, retorna valores aparados ou básicos. Use-o como "testx" .Left (4) ou str.Right (12);

Jeff Crawford
fonte
13

MSDN

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

EDIT: muito lento ...

RvdK
fonte
9

se você não tem certeza do comprimento de sua string, mas tem certeza da contagem de palavras (sempre 2 palavras neste caso, como 'xxx yyyyyy'), é melhor usar dividir.

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

isso sempre retorna a segunda palavra de sua string.

Mahdi Tahsildari
fonte
Sim; vamos apenas assumir que o texto de OP SEMPRE tem espaços em branco; como no exemplo dele :)
Christian
1
Hei Christian :) todos nós sabemos mais do que algumas linhas de uma resposta. Acabei de responder à pergunta resumidamente, é claro, há muito mais coisas a serem consideradas no código real.
Mahdi Tahsildari
7

Não é exatamente isso que você está pedindo, mas apenas olhando para o exemplo, parece que você está procurando a seção numérica da string.

Se esse for sempre o caso, uma boa maneira de fazer isso seria usar uma expressão regular.

var regex= new Regex("\n+");
string numberString = regex.Match(page).Value;
calafrios 42
fonte
-1 Expressões regulares são um pouco exageradas para algo assim, especialmente quando já existem métodos embutidos para fazer isso.
James
1
Não estou defendendo o uso desse método se você realmente precisar apenas dos últimos 6, mas se seu objetivo for extrair um número (como um id) que pode mudar para 5 ou 7 dígitos em algum momento no futuro, este é a melhor maneira.
chills42 de
1
Resposta antiga, mas +1 para apoiar o uso de expressões regulares. Especialmente porque (ainda) não há métodos embutidos na implementação de String do .NET para fazer isso @James. Caso contrário, esta questão pode nunca ter existido.
CrazyIvan1974
@ CrazyIvan1974 não tenho certeza por que você me mencionou em seu comentário
James
5

Usa isto:

String text = "PER 343573";
String numbers = text;
if (text.Length > 6)
{
    numbers = text.Substring(text.Length - 6);
}
cjk
fonte
texto? .Substring (text.Length - 6)
Ludwo
5

Adivinhando seus requisitos, mas a seguinte expressão regular produzirá apenas 6 alfanuméricos antes do final da string e nenhuma correspondência de outra forma.

string result = Regex.Match("PER 343573", @"[a-zA-Z\d]{6}$").Value;
Wade
fonte
Esta solução não atende razoavelmente aos requisitos vagos? Se não, explique o seu voto negativo.
Wade
5

Como você está usando .NET, que é compilado em MSIL , basta fazer referência a Microsoft.VisualBasic e usar o Strings.Rightmétodo integrado da Microsoft :

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

Não há necessidade de criar um método de extensão personalizado ou outro trabalho. O resultado é alcançado com uma referência e uma linha simples de código.

Como mais informações sobre isso, o uso de métodos do Visual Basic com C # foi documentado em outro lugar . Eu pessoalmente tropecei nele primeiro ao tentar analisar um arquivo, e descobri que este tópico do SO sobre o uso da Microsoft.VisualBasic.FileIO.TextFieldParserclasse é extremamente útil para analisar arquivos .csv.

Aaron Thomas
fonte
Essa abordagem também foi detalhada em outro tópico do SO aqui: stackoverflow.com/a/15255454/2658159
Aaron Thomas
Isso é MENTAL! Mas, como cara do VB, é bom comandar os CSharpers pelo menos uma vez!
SteveCinq de
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"

isso suporta qualquer número de caracteres no str. o código alternativo não suporta nullstring. e, o primeiro é mais rápido e o segundo é mais compacto.

Eu prefiro o segundo se conhecer a strstring curta. se for uma string longa, a primeira é mais adequada.

por exemplo

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"
Supawat Pusavanno
fonte
1
Eu gosto dessa alternativa. Detalhado, mas fácil de entender e lida automaticamente com o problema da string muito curta.
Andrew Grothe
3

Usa isto:

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

Brandão
fonte
3

Outra solução que não pode ser mencionada

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

Métodos de segurança nulos:

Strings mais curtos que o comprimento máximo retornando a string original

Método de extensão da string direita

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

Método de extensão da string esquerda

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

Aqui está a solução que eu uso ... Ele verifica se o comprimento da string de entrada não é menor do que o comprimento solicitado. As soluções que vejo postadas acima não levam isso em consideração, infelizmente - o que pode levar a travamentos.

    /// <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);
        }
    }
Yves Schelpe
fonte
2

Este é o método que uso: gosto de manter as coisas simples.

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

Apenas um pensamento:

public static string Right(this string @this, int length) {
    return @this.Substring(Math.Max(@this.Length - length, 0));
}
Hamid Sadeghian
fonte
1
//s - your string
//n - maximum number of right characters to take at the end of string
(new Regex("^.*?(.{1,n})$")).Replace(s,"$1")
vldmrrr
fonte
Alguém sinalizou sua postagem para exclusão e eu a vi em uma fila de revisão . Acho que sua postagem foi sinalizada incorretamente. Respostas somente de código não são de baixa qualidade . Tenta responder à pergunta? Se não, sinalize. É tecnicamente incorreto? Votar negativamente.
Wai Ha Lee de
1
O código deve ser acompanhado de uma explicação por escrito sobre como ele corrige o problema no OP.
Zze
1
Bem, eu pensei que uma explicação escrita nos comentários fosse suficiente, não?
vldmrrr
0

Sem recorrer ao conversor de bits e ao deslocamento de bits (é preciso ter certeza da codificação), este é o método mais rápido que uso como método de extensão 'Certo'.

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);
}
CJM
fonte
2
Array.Reverserecebe uma matriz, não uma string e if (myString.length > 6). Deixando de lado os erros de sintaxe, por que esse seria o método mais rápido? Certamente, apenas usar substring seria a melhor maneira, não exigiria toda essa cópia de arrays.
1800 INFORMAÇÕES
0

Eu uso o Min para prevenir as situações negativas e também lidar com strings nulas

// <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;
    }
RitchieD
fonte
0
using Microsoft.visualBasic;

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

a saída é "Word"

Steve Short
fonte