Loại bỏ các ký tự không phải số trong chuỗi


114

Xin chào, tôi đang tìm cách loại bỏ các ký tự không phải số trong một chuỗi trong ASP.NET C #

Vì vậy, tức là 40,595 pa

sẽ kết thúc với 40595

Cảm ơn


3
Đây là câu trả lời của bạn: stackoverflow.com/questions/262448/…

Câu trả lời:


234

Có nhiều cách, nhưng điều này nên làm (mặc dù không biết nó hoạt động như thế nào với các chuỗi thực sự lớn):

private static string GetNumbers(string input)
{
    return new string(input.Where(c => char.IsDigit(c)).ToArray());
}

21
Bạn có thể nên sử dụng IsDigitthay vì IsNumber: "Phương pháp này [ IsNumber] xác định xem a Charcó thuộc bất kỳ danh mục Unicode số nào hay không. Ngoài việc bao gồm các chữ số, các số còn bao gồm các ký tự, phân số, chỉ số dưới, ký tự trên, chữ số La Mã, tử số tiền tệ và số được bao quanh. Phương pháp này tương phản với IsDigitphương pháp xác định xem a có phải Charlà một chữ số cơ số 10 hay không. " msdn.microsoft.com/en-us/library/yk2b3t2y.aspx
LukeH

2
@TrevorBrooks Giả sử bạn chỉ có thể mở rộng các điều khoản:input.Where(c => char.IsDigit(c) || char.IsWhiteSpace(c))
Fredrik Mörk 23/02/15

6
Người ta có thể đơn giản hóa nó hơn nữa return new string(input.Where(char.IsDigit).ToArray());. Tôi chỉ làm cho nó dễ đọc hơn
Zapnologica

2
Câu trả lời rất hay. Có thể chỉ muốn xem xét đổi tên hàm từ 'GetNumbers' thành 'GetDigits' ... để làm rõ ý định của nó.
JTech

2
Tạo nên một phương thức mở rộng tuyệt vời.
Roberto Bonini

61

Cảm thấy rất phù hợp với một biểu thức chính quy.

var s = "40,595 p.a.";
var stripped = Regex.Replace(s, "[^0-9]", "");

"[^0-9]"có thể được thay thế bằng @"\D"nhưng tôi thích tính dễ đọc của [^0-9].


1
Tôi sẽ đồng ý miễn là bạn là okay với overhead kết hợp với biểu thức thông thường trong Net
Franko

4
Vì tò mò, hiệu suất giữa câu trả lời này và câu trả lời của Fredrik Mork là gì?
Scuba Steve

Điều này có thể chậm hơn nhưng cách duy nhất để biết là đo lường vì nó phụ thuộc vào cách .NET triển khai Biểu thức chính quy, cách Biểu thức Lambda được biên dịch và hơn thế nữa.
Jonas Elfström 28/10/16

1
Điều này linh hoạt hơn sử dụng IsDigit () vì bạn có thể thêm '.' ký tự vào regex nếu bạn muốn cho phép các số có vị trí thập phân.
Richard Moore

10
Tôi đã thực hiện một so sánh đơn giản giữa Regex và LINQ trên một chuỗi được xây dựng từ 100.000 GUID được kết hợp với nhau (dẫn đến một chuỗi 3.600.000 ký tự). Regex luôn trong khoảng nửa giây, trong khi LINQ luôn ở trong khoảng 1/10 giây. Về cơ bản, LINQ nhanh hơn trung bình từ 5 lần trở lên.
Chris Pratt

8

Một phương pháp mở rộng sẽ là một cách tiếp cận tốt hơn:

public static string GetNumbers(this string text)
    {
        text = text ?? string.Empty;
        return new string(text.Where(p => char.IsDigit(p)).ToArray());
    }

Tôi thích if (text == null) return string.Empty;hơn text = text ?? string.Empty;. Bằng cách này, chúng tôi không làm giảm hiệu suất.
Hooman

6

Sử dụng một biểu thức chính quy chỉ nắm bắt 0-9 và loại bỏ phần còn lại. Tuy nhiên, một biểu thức chính quy là một hoạt động sẽ tốn rất nhiều chi phí trong lần đầu tiên. Hoặc làm điều gì đó như thế này:

var sb = new StringBuilder();
var goodChars = "0123456789".ToCharArray();
var input = "40,595";
foreach(var c in input)
{
  if(goodChars.IndexOf(c) >= 0)
    sb.Append(c);
}
var output = sb.ToString();

Tôi nghĩ rằng một cái gì đó như vậy, tôi chưa biên soạn ..

LINQ, như Fredrik đã nói, cũng là một lựa chọn


4

Một lựa chọn khác ...

private static string RemoveNonNumberDigitsAndCharacters(string text)
{
    var numericChars = "0123456789,.".ToCharArray();
    return new String(text.Where(c => numericChars.Any(n => n == c)).ToArray());
}

2
những gì về tiêu cực? (-) không trừ được ngoài điều này?
Seabizkit

0

À, bạn biết những chữ số là gì: 0123456789 phải không? Duyệt chuỗi ký tự của bạn theo từng ký tự; nếu ký tự là một chữ số thì gắn nó vào cuối chuỗi tạm thời, nếu không thì bỏ qua. Có thể có các phương thức trợ giúp khác cho chuỗi C # nhưng đây là một phương pháp chung hoạt động ở mọi nơi.


0

Đây là mã sử dụng Biểu thức chính quy:

string str = "40,595 p.a.";

StringBuilder convert = new StringBuilder();

string pattern = @"\d+";
Regex regex = new Regex(pattern);

MatchCollection matches = regex.Matches(str);

foreach (Match match in matches)
{
convert.Append(match.Groups[0].ToString());
}

int value = Convert.ToInt32(convert.ToString()); 

Những gì tôi cần phải làm để có được Regex làm việc nhận được lỗi này Cái tên 'Regex' không tồn tại trong bối cảnh hiện nay
StevieB

sử dụng System.Text.RegularExpressions;
dhirschl

0

Câu trả lời được chấp nhận là tuyệt vời, tuy nhiên nó không tính đến giá trị NULL, do đó làm cho nó không sử dụng được trong hầu hết các trường hợp.

Điều này đã thúc đẩy tôi sử dụng các phương pháp trợ giúp này. Câu đầu tiên trả lời OP, trong khi những câu khác có thể hữu ích cho những người muốn thực hiện điều ngược lại:

    /// <summary>
    /// Strips out non-numeric characters in string, returning only digits
    /// ref.: /programming/3977497/stripping-out-non-numeric-characters-in-string
    /// </summary>
    /// <param name="input">the input string</param>
    /// <param name="throwExceptionIfNull">if set to TRUE it will throw an exception if the input string is null, otherwise it will return null as well.</param>
    /// <returns>the input string numeric part: for example, if input is "XYZ1234A5U6" it will return "123456"</returns>
    public static string GetNumbers(string input, bool throwExceptionIfNull = false)
    {
        return (input == null && !throwExceptionIfNull) 
            ? input 
            : new string(input.Where(c => char.IsDigit(c)).ToArray());
    }

    /// <summary>
    /// Strips out numeric and special characters in string, returning only letters
    /// </summary>
    /// <param name="input">the input string</param>
    /// <param name="throwExceptionIfNull">if set to TRUE it will throw an exception if the input string is null, otherwise it will return null as well.</param>
    /// <returns>the letters contained within the input string: for example, if input is "XYZ1234A5U6~()" it will return "XYZAU"</returns>
    public static string GetLetters(string input, bool throwExceptionIfNull = false)
    {
        return (input == null && !throwExceptionIfNull) 
            ? input 
            : new string(input.Where(c => char.IsLetter(c)).ToArray());
    }

    /// <summary>
    /// Strips out any non-numeric/non-digit character in string, returning only letters and numbers
    /// </summary>
    /// <param name="input">the input string</param>
    /// <param name="throwExceptionIfNull">if set to TRUE it will throw an exception if the input string is null, otherwise it will return null as well.</param>
    /// <returns>the letters contained within the input string: for example, if input is "XYZ1234A5U6~()" it will return "XYZ1234A5U6"</returns>
    public static string GetLettersAndNumbers(string input, bool throwExceptionIfNull = false)
    {
        return (input == null && !throwExceptionIfNull) 
            ? input 
            : new string(input.Where(c => char.IsLetterOrDigit(c)).ToArray());
    }

Để biết thêm thông tin, hãy đọc bài đăng này trên blog của tôi.


0
public static string RemoveNonNumeric(string value) => Regex.Replace(value, "[^0-9]", "");

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.