Menghapus karakter non-numerik dalam string

114

Hai, saya ingin menghapus karakter non-numerik dalam string di ASP.NET C #

Jadi yaitu 40.595 pa

akan berakhir dengan 40595

Terima kasih

StevieB
sumber

Jawaban:

234

Ada banyak cara, tetapi ini harus dilakukan (meskipun tidak tahu bagaimana performanya dengan string yang sangat besar):

private static string GetNumbers(string input)
{
    return new string(input.Where(c => char.IsDigit(c)).ToArray());
}
Fredrik Mörk
sumber
21
Anda mungkin sebaiknya menggunakan IsDigitdaripada IsNumber: "Metode ini [ IsNumber] menentukan apakah a Chartermasuk dalam kategori Unicode numerik. Selain memasukkan digit, angka mencakup karakter, pecahan, subskrip, superskrip, angka Romawi, pembilang mata uang, dan angka yang dilingkari. Metode ini berbeda dengan IsDigitmetode, yang menentukan apakah a Charadalah digit radix-10. " msdn.microsoft.com/en-us/library/yk2b3t2y.aspx
LukeH
2
@TrevorBrooks Misalkan Anda dapat memperluas istilah:input.Where(c => char.IsDigit(c) || char.IsWhiteSpace(c))
Fredrik Mörk
6
Seseorang dapat menyederhanakannya lebih jauh return new string(input.Where(char.IsDigit).ToArray());. Saya hanya membuatnya lebih mudah dibaca
Zapnologica
2
Jawaban bagus. Mungkin hanya ingin mempertimbangkan untuk mengganti nama fungsi dari 'GetNumbers' menjadi 'GetDigits' juga ... untuk memperjelas maksudnya.
JTech
2
Membuat metode ekstensi yang bagus juga.
Roberto Bonini
61

Terasa cocok untuk ekspresi reguler.

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

"[^0-9]"dapat diganti oleh @"\D"tetapi saya suka keterbacaan [^0-9].

Jonas Elfström
sumber
1
Saya setuju selama Anda baik-baik saja dengan overhead yang terkait dengan ekspresi reguler di .Net
FrankO
4
Karena penasaran, apa kinerja overhead antara jawaban ini, dan jawaban Fredrik Mork?
Scuba Steve
Ini mungkin lebih lambat tetapi satu-satunya cara untuk mengetahuinya adalah mengukur karena bergantung pada bagaimana .NET mengimplementasikan Ekspresi Reguler, bagaimana Ekspresi Lambda dikompilasi, dan banyak lagi.
Jonas Elfström
1
Ini lebih fleksibel daripada menggunakan IsDigit () karena Anda dapat menambahkan '.' karakter ke regex jika Anda ingin mengizinkan angka dengan tempat desimal.
Richard Moore
10
Saya melakukan perbandingan sederhana antara Regex vs. LINQ pada string yang dibuat dari 100.000 GUID yang digabungkan (menghasilkan 3.600.000 karakter string). Regex secara konsisten berada di sekitar setengah detik, sedangkan LINQ secara konsisten berada di kisaran 1/10 detik. Pada dasarnya LINQ rata-rata 5 kali lebih cepat atau lebih.
Chris Pratt
8

Metode penyuluhan akan menjadi pendekatan yang lebih baik:

public static string GetNumbers(this string text)
    {
        text = text ?? string.Empty;
        return new string(text.Where(p => char.IsDigit(p)).ToArray());
    }
Ercan Ayan
sumber
Saya lebih suka if (text == null) return string.Empty;lebih text = text ?? string.Empty;. Dengan cara ini kami tidak menurunkan kinerja.
Hooman
6

Gunakan ekspresi reguler yang hanya menangkap 0-9 dan membuang sisanya. Ekspresi reguler adalah operasi yang akan menghabiskan banyak biaya pada kali pertama. Atau lakukan sesuatu seperti ini:

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

Sesuatu seperti itu menurut saya, saya belum menyusunnya ..

LINQ, seperti yang dikatakan Fredrik, juga merupakan opsi

Onkelborg
sumber
4

Pilihan lain ...

private static string RemoveNonNumberDigitsAndCharacters(string text)
{
    var numericChars = "0123456789,.".ToCharArray();
    return new String(text.Where(c => numericChars.Any(n => n == c)).ToArray());
}
kernowcode.dll
sumber
2
bagaimana dengan yang negatif? (-) Bukankah harus dikurangi dari ini?
Seabizkit
0

Nah, tahukah Anda berapa digitnya: 0123456789, bukan? Lintasi string karakter demi karakter; jika karakternya adalah digit, tempelkan ke ujung string temp, jika tidak abaikan. Mungkin ada metode pembantu lain yang tersedia untuk string C # tetapi ini adalah pendekatan umum yang bekerja di mana-mana.

Tim
sumber
0

Berikut kode yang menggunakan Regular Expressions:

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()); 
dhirschl
sumber
Apa yang harus saya lakukan untuk mendapatkan Regex Bekerja mendapatkan kesalahan ini Nama 'Regex' tidak ada dalam konteks saat ini
StevieB
menggunakan System.Text.RegularExpressions;
dhirschl
0

Jawaban yang diterima bagus, namun tidak memperhitungkan nilai NULL, sehingga membuatnya tidak dapat digunakan di sebagian besar skenario.

Ini mendorong saya untuk menggunakan metode pembantu ini sebagai gantinya. Yang pertama menjawab OP, sementara yang lain mungkin berguna bagi yang ingin melakukan sebaliknya:

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

Untuk info tambahan, baca posting ini di blog saya.

Darkseal
sumber
0
public static string RemoveNonNumeric(string value) => Regex.Replace(value, "[^0-9]", "");
Patrick Cairns
sumber
-1
 var output = new string(input.Where(char.IsNumber).ToArray());
Emre Sevim
sumber