ฉันจะรับอักขระสี่ตัวสุดท้ายจากสตริงใน C # ได้อย่างไร


309

สมมติว่าฉันมีสตริง:

"34234234d124"

"d124"ฉันต้องการที่จะได้รับในช่วงสี่ตัวละครของสายนี้ซึ่งเป็น ฉันสามารถใช้งานSubStringได้ แต่มันต้องการโค้ดสองสามบรรทัดรวมถึงการตั้งชื่อตัวแปร

เป็นไปได้ไหมที่จะได้ผลลัพธ์นี้ในหนึ่งนิพจน์ด้วย C #


3
คุณต้องการอะไรเมื่อมีอักขระน้อยกว่า 4 ตัว
agent-j

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

3
"hello world"[-4:]ในหลามวิธีการง่ายๆคือ: ฉันหวังว่ารุ่น C # ในอนาคตจะทำให้เป็นเรื่องง่าย
พันเอก Panic

@ColonelPanic ตอนนี้คุณสามารถทำได้กับ C # 8.0: "hello world"[^4..]:-)
Frode Evensen

คำตอบ:


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

หากคุณบวกความยาวของสตริงของคุณคืออย่างน้อย 4 นั่นก็จะยิ่งสั้นลง:

mystring.Substring(mystring.Length - 4);

13
นอกจากนี้มันจะล้มเหลวหากmystringมีความยาวน้อยกว่า 4 ตัวอักษร
George Duckett

3
+1 เพราะฉันคิดว่าคุณอ่านได้ง่ายกว่า @ dtb's เล็กน้อย
George Duckett

การใส่โค้ดสองสามบรรทัด (ซึ่ง OP รู้แล้ว) และการยัดลงบนหนึ่งบรรทัดนั้นไม่เหมือนกับการแสดงออก
Buh Buh

1
ฉันชอบมัน. เรียบง่ายและสวยงามและรับประโยชน์สูงสุดดังนั้นหากสตริงของคุณน้อยกว่า 0 คุณจะไม่ได้รับข้อยกเว้นดัชนี
Bretticus

+1 ง่ายและตรงประเด็นครอบคลุมทุกฐาน วิธีการขยายที่เสนอโดย Stecya ก็ดีเช่นกัน แต่ถ้าหากคุณทำได้เพียงครั้งเดียว
Morvael

205

คุณสามารถใช้วิธีการขยาย :

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

จากนั้นโทร:

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

11
ฉันชอบสิ่งนี้ แต่ฉันอาจจะเรียกมันว่า Last () หลังจาก Substring ทั้งหมด () ไม่ใช่ GetSubstring ()
Buh Buh

21
อาจจะเรียกว่า Tail () เป็น Last clashes ด้วย Linq Extension Last ()
Craig Curtis

5
+1 สำหรับทำให้ "ยาวกว่า 1 บรรทัดมาก" มันน่ารำคาญมากที่เห็นโค้ดที่อ่านไม่ได้เนื่องจากการประหยัดบรรทัด
Fabio Milheiro

2
หรือเรียกมันว่า Right () เพื่อความสอดคล้องกับ VisualBasic ตามคำตอบของ @RJ Programmer (ฉันไม่ต้องการเพิ่มชุดประกอบอื่นเพียงหนึ่งฟังก์ชัน)
christutty

3
ฉันรักทางออกนี้
ลุค

46

สิ่งที่คุณต้องทำคือ ..

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

2
ถ้าคุณไม่ต้องการให้มีการยกเว้นจะถูกโยนถ้าความยาวน้อยกว่า 4 ...
Milos Mrdovic

45

ตกลงดังนั้นฉันเห็นว่านี่เป็นโพสต์เก่า แต่ทำไมเราเขียนรหัสที่ให้ไว้ในกรอบแล้ว?

ฉันขอแนะนำให้คุณเพิ่มการอ้างอิงไปยังกรอบ DLL "Microsoft.VisualBasic"

using Microsoft.VisualBasic;
//...

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

8
ตัวอย่างที่ดีของเวลาที่ใช้ฟังก์ชั่น VB
Brian White

3
ผมรักคุณ. ประสบการณ์การเขียนโปรแกรมส่วนใหญ่ของฉันคือ VB ดังนั้นการค้นหาว่าฉันสามารถใช้ฟังก์ชั่นเหล่านั้นทั้งหมดที่ฉันคุ้นเคยเป็นอย่างดี
Ben Strombeck

6
ฉันไม่สามารถทราบได้ว่าใช้ MS.VB เป็นความคิดที่ดีVisualBasicหรือไม่เพราะเหตุใดจึงเปลี่ยนเป็นเนมสเปซ TextFieldParserเป็นอีกตัวอย่างหนึ่ง เหตุใดค่าสาธารณูปโภคเหล่านี้จึงเป็นปัจจัยที่ทำให้แปลกอย่างนั้น
ruffin

6
ฉันรู้สึกเช่นนี้ควรเป็นคำตอบที่ยอมรับได้ ทำไมต้องคิดค้นล้อใหม่
แซค

2
@ บอร์กา: เรามั่นใจได้ว่ามันจะดำเนินต่อไปตราบใดที่ไมโครซอฟท์ยังคงให้การสนับสนุน Visual Basic ต่อไป มันรวมอยู่ในรุ่น 4.6 และฉันไม่สามารถหาอะไรที่ชัดเจนหรือโดยนัยจาก MS ที่พวกเขาวางแผนที่จะหยุดการสนับสนุน VB.Net เป็นภาษาการพัฒนา
RJ โปรแกรมเมอร์


26

การใช้Substringนั้นค่อนข้างสั้นและสามารถอ่านได้:

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

17

นี่เป็นอีกทางเลือกหนึ่งที่ไม่ควรดำเนินการอย่างเลวร้ายเกินไป (เนื่องจากการดำเนินการที่เลื่อนออกไป ):

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

แม้ว่าวิธีการขยายสำหรับจุดประสงค์mystring.Last(4)นั้นเป็นวิธีการแก้ปัญหาที่ชัดเจนที่สุด แต่ก็ใช้งานได้มากกว่า


1
@BrianWhite คนบ้าๆบอ ๆ หลังจากปีใหม่?
Konrad Viltersten

1
ทางออกที่ดี ฉันชอบมัน. แต่คุณลืม Reverse อื่น ๆ เพื่อรับสตริงที่ถูกต้อง ต้องเป็น: สตริงใหม่ (mystring.Reverse (). ใช้ (4) .Reverse (). ToArray ());
Yuri Morales

ใช่แล้วคุณถูกต้องแล้ว - ผู้แปลความคิดของฉันไม่ได้คิดอย่างนั้น น่าเศร้าที่ทำให้มันดูแย่ลงไปอีก! :)
Andre Luus

1
เนื่องจาก ToArray ไม่มีการดำเนินการรอการตัดบัญชี

1
ฉันไม่คิดว่าคุณเข้าใจ@BjörnAliGöranssonประเด็นของฉันคือการที่Reverse().Take(4).Reverse()แต่ละคนไม่ระบุสตริงทั้งหมดมันจะเกิดขึ้นเมื่อมีการToArrayโทรครั้งสุดท้ายเท่านั้น Reverse().ToArray().Take(4).ToArray().Reverse().ToArray()ถ้ามีไม่ได้สิ่งนั้นเป็นการดำเนินการรอการตัดบัญชีก็จะแปลให้ แน่นอนนี่ถือว่าส่วนขยายเหล่านั้นเป็นประเภทที่เลื่อนออกไป - ซึ่งฉันไม่ได้ตรวจสอบ ตัวสร้างสตริงไม่ยอมรับ IEnumerable ดังนั้นคุณต้องระบุมันไปยังอาร์เรย์ ณ จุดนั้น
Andre Luus

17

คุณสามารถใช้Substringวิธีการของ C # สำหรับอดีต

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

มันจะส่งคืนผลลัพธ์ 0000


7
มีการตอบคำถามนี้แล้ว 28 ครั้งและคุณเพิ่มอีกครั้ง และใช้สองพารามิเตอร์-เกินทำไมแทนที่จะเป็นคนเดียวเท่านั้นที่ได้รับstartIndex?
แอนดรู

คำตอบที่ฉันต้องการจริงๆขอบคุณสำหรับการแบ่งปัน @Amit Kumawat
ดาริล


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

ดี แต่ผมคิดว่าคุณหมายถึงไม่ได้= =+
dotancohen

1
mystring.Substring (mystring.Length - 4, 4) เป็นเช่นเดียวกับ: mystring.Substring (mystring.Length - 4)
Moe Howard


6

เปรียบเทียบกับคำตอบก่อนหน้านี้ข้อแตกต่างที่สำคัญคือโค้ดส่วนนี้จะพิจารณาเมื่อสตริงอินพุตคือ:

  1. โมฆะ
  2. ยาวกว่าหรือตรงกับความยาวที่ร้องขอ
  3. สั้นกว่าความยาวที่ร้องขอ

นี่มันคือ:

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

ความหมาย:

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

การใช้งาน:

GetLast("string of", 2);

ผลลัพธ์:

ของ


3

สิ่งนี้จะไม่ล้มเหลวสำหรับสตริงที่มีความยาวใด ๆ

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

นี่อาจเป็นงานมากเกินไปสำหรับงานในมือ แต่ถ้าจำเป็นต้องมีการตรวจสอบเพิ่มเติมก็สามารถเพิ่มลงในนิพจน์ปกติได้

แก้ไข: ฉันคิดว่า regex นี้จะมีประสิทธิภาพมากขึ้น:

@".{4}\Z"

5
overkill แน่นอน ฉันจะติดกับวิธีสตริงง่าย ๆ สำหรับสิ่งนี้
tsells

ตัวแปรที่สองไม่ส่งคืนสตริงตัวอักษรสามตัวเมื่อถูกเรียกด้วยอาร์กิวเมนต์ตัวอักษรสามตัวดังนั้นจึงไม่เท่ากับเวอร์ชันที่แยบยลครั้งแรกของคุณโดยใช้ lookahead เชิงลบ! :-)
avl_sweden

3

Last<T>ใช้ทั่วไป ที่จะทำงานร่วมกับใด ๆIEnumerableรวมถึงสตริง

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

และอีกอันหนึ่งสำหรับสตริง:

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

1
ว้าว. overkill อาจเป็นเช่น enumerable.Skip (enumerable.Count () - nLastElements)
Buh Buh

ฉันไม่เห็นด้วยกับ @BuhBuh เกี่ยวกับเรื่องนี้มากเกินไป แต่ฉันชอบชื่อ "สุดท้าย" ถึง "ขวา" เป็นชื่อ ฉันรู้สึกคลื่นไส้เล็กน้อยเกี่ยวกับการบรรทุกเกินพิกัด Last of IEnumerable <T> ที่มีอยู่ ฉันก็เอนตัวไปที่ "ข้าม" เช่นกัน
น่าเชื่อถือ

ฉันชอบวิธีนี้ ไม่ง่าย แต่น่าสนใจเมื่อเรียนรู้ IEnumerable
pKarelian

1

ฉันรวมรหัสบางอย่างที่ดัดแปลงจากแหล่งต่าง ๆ ที่จะได้ผลลัพธ์ที่คุณต้องการและทำสิ่งอื่น ๆ อีกมากมาย ฉันอนุญาตสำหรับค่า int เชิงลบค่า int ที่เกินความยาวของสตริงและสำหรับดัชนีสิ้นสุดจะน้อยกว่าดัชนีเริ่มต้น ในกรณีสุดท้ายนั้นเมธอดจะส่งคืนสตริงย่อยการย้อนกลับ มีความคิดเห็นมากมาย แต่แจ้งให้เราทราบหากมีสิ่งใดที่ไม่ชัดเจนหรือบ้าไปแล้ว ฉันกำลังเล่นกับสิ่งนี้เพื่อดูว่าฉันจะใช้เพื่ออะไร

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

ดังนั้นหากคุณมีสตริงเช่น "นี่คือวิธีการขยาย" นี่คือตัวอย่างและผลลัพธ์ที่คาดหวัง

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"

หวังว่ารุ่นนี้จะเป็นประโยชน์กับใครบางคน มันทำงานเหมือนปกติถ้าคุณไม่ใช้ตัวเลขติดลบใด ๆ และให้ค่าเริ่มต้นสำหรับ params นอกช่วง



1

สมมติว่าคุณต้องการสตริงระหว่างสตริงซึ่งอยู่ห่างจากอักขระ 10 ตัวสุดท้ายและคุณต้องการเพียง 3 ตัวเท่านั้น

สมมติว่า StreamSelected = "rtsp://72.142.0.230:80/SMIL-CHAN-273/4CIF-273.stream"

ในข้างต้นฉันต้องแยก"273"ว่าฉันจะใช้ในแบบสอบถามฐานข้อมูล

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

คำถามนี้ถามตัวอักษรสี่ตัวสุดท้ายในสตริงอย่างชัดเจน ดูเหมือนว่าคุณจะตอบคำถามอื่นที่เกี่ยวข้องกับการแยกสิ่งต่างๆออกจากกลางสตริง นอกจากนี้ยังSubstringช่วยให้คุณผ่านจุดเริ่มต้นและความยาวดังนั้นไม่แน่ใจว่าทำไมคุณไม่ใช้สิ่งนั้นแทนที่จะใช้Removeเพื่อลบจุดเริ่มต้นก่อน
Chris

0

อัปเดต 2020 : C # 8.0 ในที่สุดก็ทำให้เป็นเรื่องง่าย:

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

คุณยังสามารถอาร์เรย์ชิ้นในทางเดียวกันดูดัชนีและช่วง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.