Chỉ trích xuất đúng nhất n chữ cái từ một chuỗi


110

Làm cách nào tôi có thể trích xuất một substringchữ cái bao gồm sáu chữ cái ngoài cùng bên phải từ một chữ cái khácstring ?

Ví dụ: chuỗi của tôi là "PER 343573". Bây giờ tôi chỉ muốn giải nén"343573" .

Tôi có thể làm cái này như thế nào?


Bạn có thể sử dụng mã nguồn cho phương pháp VB.NET Right. Trước tiên, bạn cần chuyển đổi sang C #: Referenceource.microsoft.com/#Microsoft.VisualBasic/… Chuyển đổi sang C # bằng converter.telerik.com
Darren Griffith

nhưng mã VB dựa trên c # xâu hàm trong strings.sc
Man của chúng tôi trong Bananas

Đây thực sự không phải là một cách tốt để làm điều đó, nhưng nếu bạn đang gặp khó khăn, bạn có thể thêm một tham chiếu đến Microsoft.VisualBasic.dll và sử dụng Phương pháp đúng. Nó không phải là một phương pháp mở rộng. Bạn phải sử dụng nó như thế này:string endOfString = Strings.Right(wholeString, 6);
Alan McBee - MSFT

Câu trả lời:


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

35
Aproach này không hoạt động chính xác nếu chuỗi không dài bằng số ký tự được yêu cầu.
stevehipwell

1
Tùy thuộc vào chính xác những gì OP muốn, người ta cũng có thể ném các biểu thức chính quy vào điều này. Nếu anh ta chỉ muốn số ở cuối chuỗi, đó chắc chắn là giải pháp dễ hiểu nhất, đặc biệt khi số lượng chữ số có thể thay đổi trong một số bản nâng cấp phần mềm sau này.
Joey

2
@Johannes Rössel - Tôi là một fan hâm mộ lớn của cụm từ thông dụng (xem câu trả lời của tôi), nhưng tôi sẽ không bao giờ đề xuất chúng cho một tình huống đơn giản như thế này. Bất kỳ câu trả lời nào sử dụng trình bao bọc hàm sẽ phù hợp hơn với việc bảo trì mã hơn là một biểu thức chính quy. Phương thức mở rộng (hoặc hàm tiêu chuẩn nếu .NET 2.0) là giải pháp tốt nhất.
stevehipwell

@ Stevo3000 - có một giải pháp ném nếu chuỗi có độ dài sai là một giải pháp hợp lệ. Không phải là giải pháp duy nhất, nhưng vẫn còn.
Marc L.

3
@James - nói đúng ra là chỉ có tiêu đề đề cập đến "n chữ cái". Câu hỏi thực tế được đặt ra yêu cầu "sáu chữ cái ngoài cùng bên phải" :)
Chris Rogers

69

Viết phương thức mở rộng để thể hiện Right(n);hàm. Hàm phải xử lý các chuỗi rỗng hoặc rỗng trả về một chuỗi trống, các chuỗi ngắn hơn độ dài tối đa trả về chuỗi ban đầu và các chuỗi dài hơn độ dài tối đa trả về độ dài tối đa của các ký tự ngoài cùng bên phải.

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

Chỉ số bắt đầu cũng không được nhỏ hơn 0.
James

2
@James - Nó sẽ không giống như sValue.Length > iMaxLengthtrước khi một chuỗi con được gọi!
stevehipwell

3
Câu trả lời tuyệt vời, nhưng hơi mất thời gian để xem ký hiệu Hungary trong mã C #.
Jerad Rose

1
@JeradRose - Tôi làm việc trong một dự án mà cơ sở mã được phát triển từ ứng dụng VB3 (hầu hết là VB.NET) nên có một số tàn dư.
stevehipwell

4
@Jalle, VB.NET có Left, Right và Mid là các hàm cấp cao nhất, cộng với nhiều thứ hữu ích khác không phải là một phần của C #. Không chắc tại sao, vì nhiều người trong số họ là các chức năng tốt.
ingredient_15939

40

Có lẽ tốt hơn khi sử dụng một phương pháp mở rộng:

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

Sử dụng

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

19
Sau đó, nó sẽ ném một NullReferenceException giống như nó sẽ nếu bạn cố gắng sử dụng bất kỳ phương pháp trên một chuỗi rỗng ...
James

1
str.Length - lengthcó thể là tiêu cực. Ngoài ra, tham số thứ hai là tùy chọn. Không cần vượt qua độ dài.
iheartcsharp

1
@ JMS10 chắc chắn có thể được nhưng đó là mối quan tâm của nhiều người gọi hơn là của tôi. Ngoài ra, có điểm hợp lý, bạn có thể sử dụng ghi đè chỉ lấy một tham số ở đây.
James

str? .Substring (str.Length - chiều dài, chiều dài);
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
}

Không nên lỗi, trả về giá trị null dưới dạng chuỗi trống, trả về giá trị được cắt xén hoặc cơ sở. Sử dụng nó như "testx" .Left (4) hoặc str.Right (12);


13

MSDN

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

CHỈNH SỬA: quá chậm ...


9

nếu bạn không chắc về độ dài chuỗi của mình, nhưng bạn chắc chắn về số từ (luôn là 2 từ trong trường hợp này, chẳng hạn như 'xxx yyyyyy') thì tốt hơn bạn nên sử dụng split.

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

điều này luôn trả về từ thứ hai trong chuỗi của bạn.


Vâng; giả sử văn bản của OP LUÔN có khoảng trắng; như trong ví dụ của anh ấy :)
Christian

1
Hei Christian :) tất cả chúng ta đều biết nhiều hơn một vài dòng của một câu trả lời. Tôi chỉ trả lời câu hỏi một cách ngắn gọn, tất nhiên, có rất nhiều điều cần xem xét trong mã thực.
Mahdi Tahsildari

7

Đây không phải là chính xác những gì bạn đang yêu cầu, nhưng chỉ cần nhìn vào ví dụ, có vẻ như bạn đang tìm kiếm phần số của chuỗi.

Nếu điều này luôn xảy ra, thì một cách tốt để làm điều đó sẽ là sử dụng một biểu thức chính quy.

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

-1 biểu thức chính quy hơi quá mức cần thiết đối với một cái gì đó như thế này, đặc biệt là khi đã có sẵn các phương thức để thực hiện nó.
James

1
Tôi không tranh cãi về việc sử dụng phương pháp này nếu bạn thực sự chỉ cần số 6 cuối cùng, nhưng nếu mục tiêu của bạn là trích xuất một số (chẳng hạn như id) có thể thay đổi thành 5 hoặc 7 chữ số vào một thời điểm nào đó trong tương lai, điều này là một cách tốt hơn.
ớn lạnh 42

1
Câu trả lời cũ, nhưng +1 để hỗ trợ sử dụng cụm từ thông dụng. Đặc biệt là vì không có (vẫn) không có phương thức tích hợp nào trong quá trình triển khai Chuỗi của .NET để thực hiện @James này. Nếu không, câu hỏi này có thể chưa từng tồn tại.
CrazyIvan1974

@ CrazyIvan1974 không chắc tại sao bạn lại đề cập đến tôi trong nhận xét của bạn
James

5

Dùng cái này:

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

text? .Substring (text.Length - 6)
Ludwo 17/07/19

5

Đoán theo yêu cầu của bạn nhưng biểu thức chính quy sau sẽ chỉ mang lại 6 chữ và số trước khi kết thúc chuỗi và không có kết quả phù hợp nào khác.

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

Giải pháp này không đáp ứng một cách hợp lý các yêu cầu mơ hồ? Nếu không, vui lòng giải thích biểu quyết của bạn.
Wade

5

Vì bạn đang sử dụng .NET, mà tất cả đều biên dịch thành MSIL , chỉ cần tham khảo Microsoft.VisualBasicsử dụng Strings.Rightphương pháp tích hợp sẵn của Microsoft :

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

Không cần phải tạo một phương pháp mở rộng tùy chỉnh hoặc công việc khác. Kết quả đạt được với một tham chiếu và một dòng mã đơn giản.

Như thông tin thêm về điều này, sử dụng các phương pháp Visual Basic với C # đã được tài liệu ở nơi khác . Cá nhân tôi đã vấp phải nó đầu tiên khi cố gắng phân tích cú pháp một tệp và nhận thấy luồng SO này khi sử dụng Microsoft.VisualBasic.FileIO.TextFieldParserlớp này cực kỳ hữu ích để phân tích cú pháp tệp .csv.


Cách tiếp cận này cũng được trình bày chi tiết trong một thread SO đây: stackoverflow.com/a/15255454/2658159
Aaron Thomas

Đó là TÂM LÝ! Nhưng với tư cách là chàng trai VB, thật tuyệt khi được thống trị nó trên CSharpers một lần!
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"

điều này hỗ trợ bất kỳ số lượng ký tự nào trong str. mã thay thế không hỗ trợ nullchuỗi. và, thứ nhất nhanh hơn và thứ hai nhỏ gọn hơn.

tôi thích cái thứ hai hơn nếu biết strchuỗi ngắn có chứa. nếu nó là chuỗi dài thì cái đầu tiên phù hợp hơn.

ví dụ

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

hoặc là

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
Tôi thích sự thay thế đó. Dài dòng, nhưng dễ hiểu và tự động xử lý vấn đề chuỗi quá ngắn.
Andrew Grothe

3

Dùng cái này:

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


3

Một giải pháp khác có thể không được đề cập

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

3

Phương pháp vô hiệu:

Các chuỗi ngắn hơn độ dài tối đa trả về chuỗi ban đầu

Phương pháp mở rộng bên phải chuỗi

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

Phương pháp mở rộng bên trái chuỗi

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

2

Đây là giải pháp tôi sử dụng ... Nó kiểm tra xem độ dài của chuỗi đầu vào không thấp hơn độ dài được yêu cầu. Rất tiếc, các giải pháp tôi thấy đã đăng ở trên không tính đến vấn đề này - có thể dẫn đến sự cố.

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

Đây là phương pháp tôi sử dụng: Tôi thích giữ mọi thứ đơn giản.

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

1

Chỉ là một suy nghĩ:

public static string Right(this string @this, int length) {
    return @this.Substring(Math.Max(@this.Length - length, 0));
}

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

Ai đó đã gắn cờ bài đăng của bạn để xóa và tôi đã thấy nó trong hàng đợi xem xét . Tôi nghĩ rằng bài viết của bạn đã bị gắn cờ không chính xác. Câu trả lời chỉ có mã không có chất lượng thấp . Nó có cố gắng trả lời câu hỏi không? Nếu không, hãy gắn cờ. Nó có sai kỹ thuật không? Phản đối.
Wai Ha Lee,

1
Mã phải được kèm theo giải thích bằng văn bản về cách nó khắc phục sự cố trong OP.
Zze

1
Tôi nghĩ lời giải thích bằng văn bản trong các bình luận là đủ, phải không?
vldmrrr 13/02/18

0

Không cần dùng đến bộ chuyển đổi bit và dịch chuyển bit (cần chắc chắn về mã hóa), đây là phương pháp nhanh nhất mà tôi sử dụng làm phương pháp mở rộng 'Right'.

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.Reversenhận một mảng, không phải một chuỗi và if (myString.length > 6). Bỏ qua lỗi cú pháp, tại sao đây lại là phương pháp nhanh nhất? Chắc chắn rằng chỉ sử dụng chuỗi con sẽ là một cách tốt hơn, nó sẽ không yêu cầu tất cả việc sao chép mảng này.
THÔNG TIN 1800

0

Tôi sử dụng Min để ngăn chặn các tình huống tiêu cực và cũng xử lý các chuỗi rỗng

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

0
using Microsoft.visualBasic;

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

đầu ra là "Word"

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.