C # 'daki bir dizeden son dört karakteri nasıl alabilirim?


309

Bir dizem olduğunu varsayalım:

"34234234d124"

Bu dizenin son dört karakterini elde etmek istiyorum "d124". Kullanabilirim SubString, ancak bir değişkenin adlandırılması da dahil olmak üzere birkaç satır kod gerekiyor.

Bu sonucu C # ile bir ifadede elde etmek mümkün mü?


3
4 karakterden az olduğunda ne istiyorsunuz?
agent-j

12
4 > mystring.length ? mystring : mystring.Substring(mystring.length -4);
Jodrell

3
Python çözüm basittir: "hello world"[-4:]. Umarım gelecekteki bir C # sürümü bu kadar kolay olacaktır.
Albay Panik

@ColonelPanic, şimdi C # 8.0: "hello world"[^4..]:-) ile yapabilirsiniz
Frode Evensen

Yanıtlar:


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

Dizenizin uzunluğunun en az 4 olması olumluysa, daha da kısadır:

mystring.Substring(mystring.Length - 4);

13
Ayrıca, mystring4 karakterden daha kısa olursa başarısız olur .
George Duckett

3
+1, çünkü seninkinin @ dtb'den biraz daha okunabilir olduğunu düşünüyorum
George Duckett

Birkaç kod satırı (OP'nin zaten bildiği) almak ve bir satıra sıkıştırmak, tek bir ifade ile aynı şey değildir.
Buh Buh

1
Bunu sevdim. Basit ve zariftir.
Bretticus

+1 basit ve noktaya kadar, tüm üsleri kapsar. Stecya tarafından önerilen uzatma yöntemi de iyidir, ancak sadece bir kez yapıyorsanız biraz fazla öldürmek.
Morvael

205

Bir uzantı yöntemi kullanabilirsiniz :

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

Ve sonra arayın:

string mystring = "34234234d124";
string res = mystring.GetLast(4);

11
Bunu beğendim, ama muhtemelen sadece Last () diyorum. Sonuçta Substring (), GetSubstring () değildir.
Buh Buh

21
Linq Extension Last () ile Last çakışmaları olarak buna Tail () deyin.
Craig Curtis

5
+1 değerini "1 satırdan çok daha uzun" yapmak için. Hat tasarrufu nedeniyle okunamayan kodu görmek çok can sıkıcı.
Fabio Milheiro

2
Veya @RJ Programmer'ın cevabına göre VisualBasic ile tutarlılık için Right () olarak adlandırın (yalnızca bir işlev için başka bir derleme eklemek istemiyorum).
christutty

3
Bu çözümü seviyorum.
Luke

46

Tüm yapman gereken..

String result = mystring.Substring(mystring.Length - 4);

2
Uzunluk 4'ten azsa bir istisna atılmasını istiyorsanız ...
Milos Mrdovic

45

Tamam, bu eski bir yazı olduğunu görüyorum, ama neden zaten çerçevede sağlanan kodu yeniden yazıyoruz?

Çerçeve DLL "Microsoft.VisualBasic" için bir başvuru eklemenizi öneririz

using Microsoft.VisualBasic;
//...

string value = Strings.Right("34234234d124", 4);

8
VB işlevselliğini kullanmak için güzel bir örnek
Brian White

3
Seni seviyorum. Programlama deneyimimin çoğu VB, bu yüzden aşina olduğum tüm fonksiyonları kullanabileceğimi
öğrenmek

6
MS.VB'yi kullanmanın iyi bir fikir olup olmadığını asla anlayamıyorum - neden VisualBasicisim alanına giriyor ? TextFieldParserbaşka bir örnektir. Bu yardımcı programlar neden bu kadar tuhaf bir şekilde etkiliyor?
14'te

6
Bunun kabul edilen cevap olması gerektiğini hissediyorum. Neden tekerleği yeniden icat etti?
Zack

2
@Bomboca: Bir Microsoft Visual Basic'i desteklemeye devam ettiği sürece devam edeceğinden emin olabiliriz. 4.6 sürümüne dahildir ve MS'den VB.Net'i bir geliştirme dili olarak desteklemeyi bırakmayı planladıkları açık veya zımni hiçbir şey bulamıyorum.
RJ Programcı

30
string mystring = "34234234d124";
mystring = mystring.Substring(mystring.Length-4)

26

Substring kullanmak aslında oldukça kısa ve okunabilir:

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

17

Çok kötü performans göstermemesi gereken başka bir alternatif ( ertelenmiş yürütme nedeniyle ):

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

Her ne kadar bu amaç için bir uzatma yöntemi mystring.Last(4)açıkça olsa en temiz çözüm olsa da, biraz daha fazla iş.


1
@BrianWhite Yeni yılın ardından insanlar huysuz mu?
Konrad Viltersten

1
Güzel çözüm. bunu sevdim. Ama doğru dizeyi almak için diğer Reverse'ı unuttun. Olması gereken: new string (mystring.Reverse (). Take (4) .Reverse (). ToArray ());
Yuri Morales

Aah evet, haklısın - zihinsel derleyicim bu kadar düşünmedi. Ne yazık ki bu daha da kötü görünüyor! :)
Andre Luus

1
ToArray nedeniyle ertelenmiş bir yürütme yoktur

1
Anladığınızı sanmıyorum, @ BjörnAliGöransson, benim fikrimi, Reverse().Take(4).Reverse()her biri tüm dize numaralandırma yok, sadece son ToArrayçağrıda olur . Eğer ertelenmiş infaz diye bir şey olmasaydı, bu tercüme olurdu Reverse().ToArray().Take(4).ToArray().Reverse().ToArray(). Bu, elbette, bu uzantıların kontrol etmediğim ertelenmiş tür olduğunu varsayar. Dize yapıcıları IEnumerable kabul etmez, bu nedenle o noktada bir diziye numaralandırmak gerekir.
Andre Luus

17

Sadece SubstringC # yöntemini kullanabilirsiniz . Örn.

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

Sonuç 0000 döndürecektir.


7
Bu 28 kez cevaplandı ve tekrar eklediniz mi? Ve neden sadece alanın yerine iki parametreli aşırı yükü kullanalım startIndex?
Andrew

Tam cevap ihtiyacım vardı. @Amit Kumawat paylaştığınız için teşekkürler.
Daryl

12

Basit bir çözüm:

string mystring = "34234234d124";
string last4 = mystring.Substring(mystring.Length - 4, 4);

7
mystring = mystring.Length > 4 ? mystring.Substring(mystring.Length - 4, 4) : mystring;

Güzel, ama demek olduğunu düşünüyorum =değildir =+.
dotancohen

1
mystring.Substring (mystring.Length - 4, 4) aynıdır: mystring.Substring (mystring.Length - 4)
Moe Howard

6

Sadece bu:

int count = 4;
string sub = mystring.Substring(mystring.Length - count, count);

6

Önceki bazı cevaplarla karşılaştırıldığında, temel fark, giriş dizesi şu olduğunda bu kod parçasının dikkate alınmasıdır:

  1. Boş
  2. İstenen uzunluktan daha uzun veya eşleştirme
  3. İstenen uzunluktan daha kısa.

İşte burada:

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

4

Tanım:

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

Kullanımı:

GetLast("string of", 2);

Sonuç:

nın-nin


3

Bu, herhangi bir uzunluk dizesi için başarısız olmaz.

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

Bu muhtemelen eldeki görev için aşırıdır, ancak ek doğrulama olması gerekiyorsa, muhtemelen normal ifadeye eklenebilir.

Düzenleme: Bu normal ifade daha verimli olacağını düşünüyorum:

@".{4}\Z"

5
Kesinlikle abartılı. Bunun için basit dize yöntemleri ile sopa.
tsells

İkinci değişken, üç harfli bir argümanla çağrıldığında üç harfli bir dize döndürmez, bu nedenle negatif ileriye dönük kullanan ilk dahice sürümünüzle eşdeğer değildir! :-)
avl_sweden

3

Genel kullanın Last<T>. IEnumerableDize dahil olmak üzere HERHANGİ biriyle çalışır .

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

Ve dize için belirli bir tane:

public static string Right(this string str, int nLastElements)
{
    return new string(str.Last(nLastElements).ToArray());
}

1
Vay. Aşırı yükleme. Belki enumerable.Skip (enumerable.Count () - nLastElements) gibi bir şey?
Buh Buh

@BuhBuh ile bu aşırıya kaçma hakkında katılmıyorum. Ama isim olarak "Son" u "Doğru" ya tercih ediyorum. Mevcut Son EnEnumerable <T> aşırı yüklenmesi konusunda biraz cılızım. Ben de "Atla" ya yöneliyorum.
Şubat'ta

Bu çözümü seviyorum. Basit değil ama IEnumerable öğrenirken ilgi çekici.
pKareliyen

1

İstediğiniz sonuçları elde etmek ve daha fazlasını yapmak için çeşitli kaynaklardan değiştirilmiş bazı kodları bir araya getirdim. Negatif int değerleri, dizenin uzunluğunu aşan int değerleri ve son dizin başlangıç ​​dizininden daha az olması için izin verdim. Bu son durumda, yöntem bir ters sıralı alt dize döndürür. Çok sayıda yorum var, ancak bir şeyin belirsiz veya sadece deli olup olmadığını bana bildirin. Ne için kullanabileceğimi görmek için bununla oynuyordum.

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

"Bu bir uzantı yöntemidir" gibi bir dizeniz varsa, işte size bazı örnekler ve sonuçlar.

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"

Umarım bu sürüm birisi için yararlıdır. Negatif sayılar kullanmazsanız normal gibi çalışır ve aralık dışı parametreler için varsayılan değerler sağlar.


1
string var = "12345678";

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

// result = "5678"

1

dizeleri son karakterden 10 karakter içeren bir dize arasında istediğinizi varsayarsak ve sadece 3 karaktere ihtiyacınız vardır.

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

Yukarıda, ben "273"veritabanı sorgusunda kullanacağım ayıklamak gerekir

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

Bu soru, dizede son dört karakteri açıkça soruyor. Dizenin ortasından bir şeyler çıkarmayla ilgili farklı bir soruyu yanıtlıyor gibisiniz. Ayrıca Substringzaten bir başlangıç ​​noktası ve uzunluğu geçirmenize izin verir, bu yüzden Removeönce başlangıcı kaldırmak için kullanmak yerine neden bunu kullanmayacağınızdan emin değilsiniz .
Chris

0

2020 Güncellemesi : C # 8.0 sonunda bunu kolaylaştırır:

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

Ayrıca dizileri aynı şekilde dilimleyebilirsiniz, bkz. Endeksler ve aralıklar .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.