Bagaimana cara mendapatkan empat karakter terakhir dari string dalam C #?


309

Misalkan saya punya string:

"34234234d124"

Saya ingin mendapatkan empat karakter terakhir dari string ini yaitu "d124". Saya dapat menggunakan SubString, tetapi perlu beberapa baris kode, termasuk penamaan variabel.

Apakah mungkin mendapatkan hasil ini dalam satu ekspresi dengan C #?


3
Apa yang Anda inginkan ketika jumlah karakter kurang dari 4?
agen-j

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

3
Dalam Python solusinya sederhana: "hello world"[-4:]. Saya harap versi C # di masa depan akan membuatnya mudah.
Kolonel Panic

@ ColonelPanic, sekarang Anda bisa dengan C # 8.0: "hello world"[^4..]:-)
Frode Evensen

Jawaban:


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

Jika Anda yakin panjang string Anda setidaknya 4, maka itu lebih pendek:

mystring.Substring(mystring.Length - 4);

13
Juga, itu akan gagal jika mystringkurang dari 4 karakter.
George Duckett

3
Memberi +1 karena saya pikir milik Anda sedikit lebih mudah dibaca daripada @ dtb
George Duckett

Mengambil beberapa baris kode (yang sudah diketahui OP) dan menjejalkannya ke dalam satu baris tidak benar-benar sama dengan satu ekspresi.
Buh Buh

1
Saya suka itu. Sederhana dan elegan dan mengambil maksimal jadi jika string Anda kurang dari 0 Anda tidak akan mendapatkan pengecualian indeks.
Bretticus

+1 sederhana dan to the point, mencakup semua pangkalan. Metode ekstensi yang diusulkan oleh Stecya juga bagus, tetapi sedikit lebih dari membunuh jika Anda hanya melakukannya sekali.
Morvael

205

Anda dapat menggunakan metode ekstensi :

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

Dan kemudian telepon:

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

11
Saya suka ini, tapi saya mungkin akan menyebutnya Terakhir (). Setelah semua Substring () bukan GetSubstring ().
Buh Buh

21
Mungkin menyebutnya Tail () sebagai bentrokan Terakhir dengan Linq Extension Last ().
Craig Curtis

5
+1 untuk menjadikannya "lebih lama dari 1 baris". Sangat menjengkelkan melihat kode yang tidak dapat dibaca karena penghematan baris.
Fabio Milheiro

2
Atau panggil Right () untuk konsistensi dengan VisualBasic sesuai jawaban @RJ Programmer (saya tidak ingin menambahkan rakitan lain hanya untuk satu fungsi).
christutty

3
Saya suka solusi ini.
Luke

46

Yang harus Anda lakukan adalah ..

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

2
Tidak jika Anda ingin pengecualian dilemparkan jika panjangnya kurang dari 4 ...
Milos Mrdovic

45

Ok, jadi saya melihat ini adalah posting lama, tetapi mengapa kita menulis ulang kode yang sudah disediakan dalam framework?

Saya akan menyarankan Anda menambahkan referensi ke kerangka kerja DLL "Microsoft.VisualBasic"

using Microsoft.VisualBasic;
//...

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

8
Contoh yang bagus tentang waktu untuk menggunakan fungsionalitas VB
Brian White

3
Aku cinta kamu. Sebagian besar pengalaman pemrograman saya adalah VB, jadi mengetahui bahwa saya dapat menggunakan semua fungsi yang sangat saya kenal itu luar biasa
Ben Strombeck

6
Saya tidak pernah tahu jika menggunakan MS.VB ide yang bagus - mengapa itu didorong ke VisualBasicnamespace? TextFieldParseradalah contoh lain. Mengapa utilitas ini diperhitungkan begitu aneh?
ruffin

6
Saya merasa ini harus menjadi jawaban yang diterima. Mengapa menemukan kembali roda?
Zack

2
@Bomboca: Kita dapat yakin bahwa itu akan terus berlanjut selama Microsoft terus mendukung Visual Basic. Itu termasuk dalam rilis 4.6 dan saya tidak dapat menemukan apa pun baik tersurat maupun tersirat dari MS bahwa mereka berencana untuk berhenti mendukung VB.Net sebagai bahasa pengembangan.
Programmer RJ

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

26

Menggunakan Substring sebenarnya cukup singkat dan mudah dibaca:

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

17

Berikut adalah alternatif lain yang tidak seharusnya berkinerja terlalu buruk (karena eksekusi yang ditangguhkan ):

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

Meskipun metode ekstensi untuk tujuan mystring.Last(4)tersebut jelas merupakan solusi terbersih, meskipun sedikit lebih banyak pekerjaan.


1
@BrianWhite Orang-orang ngambek setelah tahun baru?
Konrad Viltersten

1
Solusi bagus saya suka itu. Tetapi Anda lupa Reverse lainnya untuk mendapatkan string yang benar. Harus: string baru (mystring.Reverse (). Ambil (4) .Reverse (). ToArray ());
Yuri Morales

Aah ya, Anda benar - kompiler mental saya tidak berpikir sejauh itu. Sayangnya itu membuatnya tampak lebih buruk! :)
Andre Luus

1
Karena ToArray tidak ada eksekusi yang ditangguhkan

1
Saya tidak berpikir Anda mengerti, @ BjörnAliGöransson, maksud saya adalah bahwa Reverse().Take(4).Reverse()jangan masing-masing menyebutkan seluruh string, itu hanya terjadi pada ToArraypanggilan terakhir . Jika tidak ada eksekusi yang ditangguhkan, itu akan diterjemahkan menjadi Reverse().ToArray().Take(4).ToArray().Reverse().ToArray(). Ini, tentu saja, mengasumsikan ekstensi itu adalah jenis yang ditangguhkan - yang saya tidak periksa. Konstruktor string tidak menerima IEnumerable, jadi Anda harus menghitungnya ke array pada saat itu.
Andre Luus

17

Anda cukup menggunakan Substringmetode C #. Misalnya

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

Ini akan mengembalikan hasil 0000.


7
Ini telah dijawab seperti 28 kali dan Anda menambahkannya lagi? Dan mengapa menggunakan dua-parameter-overload daripada yang hanya menerima startIndex?
Andrew

Tepat jawaban yang saya butuhkan. Terima kasih telah berbagi @Amit Kumawat.
Daryl

12

Solusi sederhana adalah:

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

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

Bagus, tapi saya pikir Anda =tidak bermaksud begitu =+.
dotancohen

1
mystring.Substring (mystring.Length - 4, 4) sama dengan: mystring.Substring (mystring.Length - 4)
Moe Howard

6

Hanya ini:

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

6

Dibandingkan dengan beberapa jawaban sebelumnya, perbedaan utama adalah bagian kode ini mempertimbangkan ketika string input adalah:

  1. Batal
  2. Lebih panjang dari atau cocok dengan panjang yang diminta
  3. Lebih pendek dari panjang yang diminta.

Ini dia:

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

Definisi:

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

Pemakaian:

GetLast("string of", 2);

Hasil:

dari


3

Ini tidak akan gagal untuk string panjang apa pun.

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

Ini mungkin berlebihan untuk tugas yang dihadapi, tetapi jika perlu ada validasi tambahan, itu mungkin dapat ditambahkan ke ekspresi reguler.

Sunting: Saya pikir regex ini akan lebih efisien:

@".{4}\Z"

5
Pasti berlebihan. Saya akan tetap menggunakan metode string sederhana untuk ini.
tsells

Varian kedua tidak mengembalikan string tiga huruf ketika dipanggil dengan argumen tiga huruf, jadi itu tidak setara dengan versi cerdik pertama Anda menggunakan lookahead negatif! :-)
avl_sweden

3

Gunakan obat generik Last<T>. Itu akan bekerja dengan APAPUN IEnumerable, termasuk 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);
    }
}

Dan yang spesifik untuk string:

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

1
Wow. Berlebihan. Mungkin sesuatu seperti enumerable.Skip (enumerable.Count () - nLastElements)?
Buh Buh

Saya tidak setuju dengan @BuhBuh tentang ini karena terlalu banyak membunuh. Tapi saya lebih suka "Terakhir" daripada "Benar" sebagai nama. Saya sedikit mual tentang overloading terakhir IEnumerable <T>. Saya agak condong ke arah "Lewati," juga.
akal

Saya suka solusi ini. Tidak sederhana tetapi menarik ketika belajar IEnumerable.
pKarelian

1

Saya mengumpulkan beberapa kode yang dimodifikasi dari berbagai sumber yang akan mendapatkan hasil yang Anda inginkan, dan melakukan lebih banyak lagi selain itu. Saya mengizinkan nilai int negatif, nilai int yang melebihi panjang string, dan indeks akhir lebih kecil dari indeks awal. Dalam kasus terakhir, metode mengembalikan substring urutan terbalik. Ada banyak komentar, tetapi beri tahu saya jika ada yang tidak jelas atau hanya gila. Saya bermain-main dengan ini untuk melihat apa yang mungkin saya gunakan untuk itu.

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

Jadi jika Anda memiliki string seperti "Ini adalah metode ekstensi", berikut adalah beberapa contoh dan hasil yang diharapkan.

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"

Semoga versi ini bermanfaat bagi seseorang. Ini beroperasi seperti biasa jika Anda tidak menggunakan angka negatif apa pun, dan memberikan standar untuk param di luar rentang.


1
string var = "12345678";

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

// result = "5678"

1

dengan asumsi Anda menginginkan string di antara string yang terletak 10 karakter dari karakter terakhir dan Anda hanya perlu 3 karakter.

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

Di atas, saya perlu mengekstrak "273"yang akan saya gunakan dalam permintaan basis data

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

Pertanyaan ini secara eksplisit menanyakan empat karakter terakhir dalam string. Anda sepertinya menjawab pertanyaan yang berbeda terkait dengan mengekstraksi sesuatu dari tengah-tengah string. Juga Substringsudah memungkinkan Anda melewati titik awal dan panjang jadi tidak yakin mengapa Anda tidak akan menggunakannya daripada menggunakan Removeuntuk menghapus awal lebih dulu.
Chris

0

Pembaruan 2020 : C # 8.0 akhirnya membuatnya mudah:

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

Anda juga dapat mengiris array dengan cara yang sama, lihat Indeks dan rentang .

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.