แยกเฉพาะตัวอักษร n ส่วนใหญ่จากสตริง


110

ฉันจะแยกsubstringตัวอักษรที่ประกอบด้วยตัวอักษรหกตัวขวาสุดออกจากตัวอักษรอื่นได้stringอย่างไร

Ex: "PER 343573"สตริงของฉันคือ "343573"ตอนนี้ผมต้องการที่จะดึงเท่านั้น

ฉันจะทำเช่นนี้ได้อย่างไร?


คุณสามารถใช้ซอร์สโค้ดสำหรับวิธี VB.NET Right คุณต้องแปลงเป็น C # ก่อน: referencesource.microsoft.com/#Microsoft.VisualBasic/…แปลงเป็น C # โดยใช้converter.telerik.com
Darren Griffith

แต่รหัส VB ​​อาศัยฟังก์ชัน c # Substring ใน strings.sc
Our Man in Bananas

นี่ไม่ใช่วิธีที่ดีมากนัก แต่ถ้าคุณไม่สะดวกคุณสามารถเพิ่มข้อมูลอ้างอิงไปยัง Microsoft.VisualBasic.dll และใช้วิธีการที่เหมาะสม ไม่ใช่วิธีการขยาย คุณต้องใช้แบบนี้:string endOfString = Strings.Right(wholeString, 6);
Alan McBee - MSFT

3
อาจซ้ำกันได้ของHow to get 4 character last from a string in c #?
drzaus

คำตอบ:


156
string SubString = MyString.Substring(MyString.Length-6);

35
aproach นี้ทำงานไม่ถูกต้องหากสตริงไม่ยาวเท่ากับจำนวนอักขระที่ต้องการ
stevehipwell

1
ขึ้นอยู่กับว่า OP ต้องการอะไรกันแน่อาจมีการใช้นิพจน์ทั่วไปในเรื่องนี้ ถ้าเขาต้องการเพียงตัวเลขที่อยู่ท้ายสตริงนั่นเป็นวิธีแก้ปัญหาที่ไม่เจ็บปวดที่สุดโดยเฉพาะอย่างยิ่งเมื่อจำนวนตัวเลขอาจแตกต่างกันไปในการอัปเกรดซอฟต์แวร์ในภายหลัง
โจอี้

2
@Johannes Rössel - ฉันเป็นแฟนตัวยงของการแสดงออกปกติ (ดูคำตอบของฉัน) แต่ฉันไม่เคยแนะนำพวกเขาสำหรับสถานการณ์ง่ายๆเช่นนี้ คำตอบใด ๆ ที่ใช้ฟังก์ชัน wrapper จะเหมาะกับการบำรุงรักษาโค้ดมากกว่านิพจน์ทั่วไป วิธีการขยาย (หรือฟังก์ชันมาตรฐานถ้า. NET 2.0) เป็นทางออกที่ดีที่สุด
stevehipwell

@ Stevo3000 - การมีโซลูชันที่พ่นหากสตริงมีความยาวไม่ถูกต้องเป็นวิธีแก้ปัญหาที่ถูกต้อง ไม่ใช่ทางออกเดียว แต่ยังคง
Marc L.

3
@ เจมส์ - เพื่อให้เข้าใจผิดเฉพาะชื่อที่กล่าวถึง "n ตัวอักษร" คำถามจริงที่ถามคือ "ตัวอักษรหกตัวขวาสุด" :)
Chris Rogers

69

เขียนวิธีการขยายเพื่อแสดงRight(n);ฟังก์ชัน ฟังก์ชันควรจัดการกับสตริงว่างหรือว่างที่ส่งคืนสตริงว่างสตริงที่สั้นกว่าความยาวสูงสุดที่ส่งคืนสตริงเดิมและสตริงที่ยาวกว่าความยาวสูงสุดที่ส่งคืนความยาวสูงสุดของอักขระขวาสุด

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

ดัชนีเริ่มต้นต้องไม่น้อยกว่า 0
เจมส์

2
@ เจมส์ - มันจะไม่เหมือนsValue.Length > iMaxLengthก่อนที่จะมีการเรียกสตริงย่อย!
stevehipwell

3
คำตอบที่ดี แต่การดูสัญกรณ์ภาษาฮังการีในรหัส C # ต้องใช้เวลาสองครั้ง
เจอราดโรส

1
@JeradRose - ฉันทำงานในโครงการที่ฐานรหัสพัฒนามาจากแอปพลิเคชัน VB3 (ส่วนใหญ่คือ VB.NET) ดังนั้นจึงมีบางส่วนที่เหลืออยู่
stevehipwell

4
@Jalle, VB.NET มีฟังก์ชันซ้ายขวาและกลางเป็นฟังก์ชันระดับบนสุดรวมถึงสิ่งที่เป็นประโยชน์อื่น ๆ อีกมากมายที่ไม่ได้เป็นส่วนหนึ่งของ C # ไม่แน่ใจว่าทำไมเนื่องจากหลายคนเป็นฟังก์ชันที่ดี
ส่วนผสม

40

น่าจะดีกว่าที่จะใช้วิธีการขยาย:

public static class StringExtensions
{
    public static string Right(this string str, int length)
    {
        return str.Substring(str.Length - length, length);
    }
}

การใช้งาน

string myStr = "PER 343573";
string subStr = myStr.Right(6);

19
จากนั้นมันจะโยน NullReferenceException เช่นเดียวกับที่คุณพยายามใช้วิธีใด ๆ บนสตริงว่าง ...
James

1
str.Length - lengthอาจเป็นลบ พารามิเตอร์ที่สองเป็นทางเลือก ไม่ต้องผ่านความยาว
iheartcsharp

1
@ JMS10 อาจเป็นได้อย่างแน่นอน แต่นั่นทำให้ผู้โทรกังวลมากกว่าของฉัน นอกจากนี้ใช่จุดยุติธรรมคุณสามารถใช้การแทนที่ที่ใช้พารามิเตอร์เดียวที่นี่
เจมส์

str? .ubstring (str.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
}

ไม่ควรเกิดข้อผิดพลาดให้คืนค่า null เป็นสตริงว่างส่งกลับค่าที่ถูกตัดหรือค่าฐาน ใช้มันเช่น "testx" .Left (4) หรือ str.Right (12);



9

หากคุณไม่แน่ใจในความยาวของสตริงของคุณ แต่คุณแน่ใจว่ามีการนับจำนวนคำ (มักจะมี 2 คำในกรณีนี้เช่น "xxx yyyyyy") คุณควรใช้การแยก

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

สิ่งนี้จะส่งกลับคำที่สองของสตริงของคุณเสมอ


ใช่; สมมติว่าข้อความของ OP เสมอมีช่องว่างสีขาว เหมือนในตัวอย่างของเขา:)
คริสเตียน

1
Hei Christian :) เราทุกคนรู้คำตอบมากกว่าสองสามบรรทัด ฉันเพิ่งตอบคำถามโดยสังเขปแน่นอนว่ามีหลายสิ่งหลายอย่างที่ต้องพิจารณาในโค้ดจริง
Mahdi Tahsildari

7

นี่ไม่ใช่สิ่งที่คุณต้องการ แต่เพียงแค่ดูตัวอย่างดูเหมือนว่าคุณกำลังมองหาส่วนตัวเลขของสตริง

หากเป็นเช่นนี้เสมอวิธีที่ดีก็คือการใช้นิพจน์ทั่วไป

var regex= new Regex("\n+");
string numberString = regex.Match(page).Value;

-1 นิพจน์ทั่วไปมีค่าใช้จ่ายมากเกินไปสำหรับบางสิ่งเช่นนี้โดยเฉพาะอย่างยิ่งเมื่อมีเมธอดในตัวอยู่แล้ว
James

1
ฉันไม่เถียงว่าจะใช้วิธีนี้ถ้าคุณต้องการแค่ 6 ตัวสุดท้าย แต่ถ้าเป้าหมายของคุณคือการดึงตัวเลข (เช่น id) ที่อาจเปลี่ยนเป็น 5 หรือ 7 หลักในบางจุดในอนาคตสิ่งนี้ เป็นวิธีที่ดีกว่า
หนาวสั่น 42

1
คำตอบเก่า แต่ +1 เพื่อรองรับการใช้นิพจน์ทั่วไป โดยเฉพาะอย่างยิ่งเนื่องจากยังไม่มีเมธอดในตัวในการใช้งาน String ของ. NET สำหรับการทำ @James นี้ มิฉะนั้นคำถามนี้อาจไม่เคยมีมาก่อน
CrazyIvan1974

@ CrazyIvan1974 ไม่แน่ใจว่าทำไมคุณถึงพูดถึงฉันในความคิดเห็นของคุณ
James

5

ใช้สิ่งนี้:

String text = "PER 343573";
String numbers = text;
if (text.Length > 6)
{
    numbers = text.Substring(text.Length - 6);
}

text? .ubstring (text.Length - 6)
Ludwo

5

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

string result = Regex.Match("PER 343573", @"[a-zA-Z\d]{6}$").Value;

โซลูชันนี้ไม่ตรงตามข้อกำหนดที่คลุมเครืออย่างสมเหตุสมผลหรือไม่? ถ้าไม่โปรดอธิบายการลงคะแนนของคุณ
ลุย

5

เนื่องจากคุณใช้. NET ซึ่งคอมไพล์ไปยังMSILเพียงอ้างอิงMicrosoft.VisualBasicและใช้Strings.Rightวิธีการในตัวของ Microsoft :

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

ไม่จำเป็นต้องสร้างวิธีการขยายแบบกำหนดเองหรืองานอื่น ๆ ผลลัพธ์ที่ได้คือการอ้างอิงหนึ่งบรรทัดและโค้ดง่ายๆหนึ่งบรรทัด

ในฐานะที่เป็นข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้โดยใช้วิธีการ Visual Basic ด้วย C # ได้รับการบันทึกไว้ในที่อื่น โดยส่วนตัวฉันสะดุดกับมันก่อนเมื่อพยายามแยกวิเคราะห์ไฟล์และพบว่าเธรด SO นี้เกี่ยวกับการใช้Microsoft.VisualBasic.FileIO.TextFieldParserคลาสเพื่อเป็นประโยชน์อย่างยิ่งสำหรับการแยกวิเคราะห์ไฟล์. csv


วิธีนี้ยังมีรายละเอียดอยู่ในเธรด SO อื่นที่นี่: stackoverflow.com/a/15255454/2658159
Aaron Thomas

นั่นคือ MENTAL! แต่ในฐานะคนที่แต่งตัวประหลาด VB เป็นเรื่องดีที่ได้ครอบครอง CSharpers สักครั้ง!
SteveCinq

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"

สิ่งนี้รองรับอักขระจำนวนเท่าใดก็ได้ในไฟล์str. รหัสทางเลือกไม่รองรับnullสตริง และครั้งแรกเร็วกว่าและวินาทีมีขนาดกะทัดรัดกว่า

ฉันชอบอันที่สองถ้ารู้strสตริงสั้น ๆ ถ้าเป็นสตริงยาวอันแรกจะเหมาะสมกว่า

เช่น

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

หรือ

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"

1
ฉันชอบทางเลือกนั้น Verbose แต่เข้าใจง่ายและจัดการปัญหาสตริงสั้นเกินไปโดยอัตโนมัติ
Andrew Grothe



3

วิธีที่ปลอดภัยเป็นโมฆะ:

สตริงที่สั้นกว่าความยาวสูงสุดที่ส่งคืนสตริงเดิม

วิธีการขยายสายอักขระขวา

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

วิธีการขยายสตริงด้านซ้าย

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

2

นี่คือวิธีแก้ปัญหาที่ฉันใช้ ... ตรวจสอบว่าความยาวของสตริงอินพุตไม่ต่ำกว่าความยาวที่ถาม วิธีแก้ปัญหาที่ฉันเห็นโพสต์ข้างต้นไม่ได้คำนึงถึงสิ่งนี้อย่างน่าเสียดายซึ่งอาจนำไปสู่ข้อขัดข้อง

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

2

นี่คือวิธีที่ฉันใช้: ฉันชอบทำให้สิ่งต่างๆเรียบง่าย

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


1
//s - your string
//n - maximum number of right characters to take at the end of string
(new Regex("^.*?(.{1,n})$")).Replace(s,"$1")

ใครบางคนถูกตั้งค่าสถานะโพสต์ของคุณสำหรับการลบและฉันเห็นมันอยู่ในคิวรีวิว ฉันคิดว่าโพสต์ของคุณถูกตั้งค่าสถานะไม่ถูกต้อง คำตอบรหัสเท่านั้นไม่ได้มีคุณภาพต่ำ มันพยายามตอบคำถามหรือไม่? ถ้าไม่ใช่ให้ตั้งค่าสถานะ ผิดทางเทคนิคหรือไม่? โหวตลง
Wai Ha Lee

1
โค้ดควรมาพร้อมกับคำอธิบายเป็นลายลักษณ์อักษรเกี่ยวกับวิธีแก้ไขปัญหาใน OP
Zze

1
ฉันคิดว่าคำอธิบายเป็นลายลักษณ์อักษรในความคิดเห็นเพียงพอแล้วใช่ไหม
vldmrrr

0

โดยไม่ต้องใช้ตัวแปลงบิตและการเปลี่ยนบิต (ต้องแน่ใจว่าเข้ารหัส) นี่เป็นวิธีที่เร็วที่สุดที่ฉันใช้เป็นวิธีการขยาย 'ขวา'

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

2
Array.Reverseรับอาร์เรย์ไม่ใช่สตริงและif (myString.length > 6). นอกจากข้อผิดพลาดทางไวยากรณ์เหตุใดจึงเป็นวิธีที่เร็วที่สุด แน่นอนว่าการใช้สตริงย่อยจะเป็นวิธีที่ดีกว่าโดยไม่จำเป็นต้องมีการคัดลอกอาร์เรย์ทั้งหมดนี้
1800 ข้อมูล

0

ฉันใช้ Min เพื่อป้องกันสถานการณ์เชิงลบและจัดการสตริงว่าง

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

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