Dizede sayısal olmayan karakterlerin çıkarılması


Yanıtlar:


237

Pek çok yolu vardır, ancak bunun yapılması gerekir (gerçi gerçekten büyük dizelerle nasıl performans gösterdiğini bilmiyorum):

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

21
Muhtemelen kullanmalıdır IsDigityerine IsNumber: "Bu yöntemle [ IsNumber] Bir belirler Char. Herhangi bir sayısal Unicode kategorisi olan hane dahil etmenin yanı sıra, sayıları karakterleri, kesirler, alt simgeler, üst simgeler, Roma rakamlarını, döviz numaratörleri ve kuşatılmış numaraları dahil Bu yöntem. a'nın radix-10 basamaklı IsDigitolup olmadığını belirleyen yöntemle çelişir Char. " msdn.microsoft.com/en-us/library/yk2b3t2y.aspx
LukeH

2
@TrevorBrooks, şartları genişletebileceğinizi varsayalım:input.Where(c => char.IsDigit(c) || char.IsWhiteSpace(c))
Fredrik Mörk

6
Kişi bunu daha da basitleştirebilir return new string(input.Where(char.IsDigit).ToArray());. Sadece daha okunaklı hale getiriyorum
Zapnologica

2
Güzel cevap. Amacını netleştirmek için işlevi 'GetNumbers' yerine 'GetDigits' olarak yeniden adlandırmayı düşünebilirsiniz.
JTech

2
Ayrıca harika bir uzatma yöntemi yapar.
Roberto Bonini

61

Normal bir ifade için iyi bir uyum gibi geliyor.

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

"[^0-9]"ile değiştirilebilir @"\D"ama okunabilirliğini seviyorum [^0-9].



4
Meraktan, bu cevap ile Fredrik Mork'un cevabı arasındaki performans ek yükü nedir?
Tüplü Steve

Bu muhtemelen daha yavaştır, ancak ölçmenin tek yolu ölçmektir çünkü .NET'in Normal İfadeleri nasıl uyguladığına, Lambda İfadesinin nasıl derlendiğine ve daha fazlasına bağlıdır.
Jonas Elfström

1
Bu, '.' Ekleyebileceğiniz için IsDigit () kullanmaktan daha esnektir. ondalık basamaklı sayılara izin vermek istiyorsanız normal ifadeye karakter.
Richard Moore

10
Birleştirilmiş 100.000 GUID'den oluşturulmuş bir dizede Regex ile LINQ arasında basit bir karşılaştırma yaptım (3.600.000 karakter dizesiyle sonuçlandı). Normal ifade tutarlı bir şekilde yarım saniyeydi, LINQ ise sürekli olarak saniyenin 1 / 10'undaydı. Temel olarak LINQ, ortalamada 5 veya daha fazla kat daha hızlıydı.
Chris Pratt

8

Bir uzatma yöntemi daha iyi bir yaklaşım olacaktır:

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

Ben tercih if (text == null) return string.Empty;üzerinde text = text ?? string.Empty;. Bu şekilde performansı düşürmeyiz.
Hooman

6

Yalnızca 0-9'u yakalayan ve gerisini çöpe atan normal bir ifade kullanın. Normal ifade, ilk seferinde çok pahalıya mal olacak bir işlemdir. Veya bunun gibi bir şey yapın:

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

Sanırım buna benzer bir şey, derlemedim ..

LINQ, Fredrik'in dediği gibi,


4

Başka seçenek ...

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

2
peki ya olumsuz? (-) eksi bunun dışında olmamalı mı?
Seabizkit

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

Ondalık sayılara izin verdikten sonra bu benim için çalışacak.
John Lord

0

Peki, rakamların ne olduğunu biliyorsun: 0123456789, değil mi? Karakter dizinizi karakter karakter çaprazlayın; karakter bir rakamsa, onu geçici bir dizenin sonuna yapıştır, aksi takdirde yok say. C # dizeleri için kullanılabilen başka yardımcı yöntemler olabilir, ancak bu, her yerde çalışan genel bir yaklaşımdır.


0

Normal İfadeleri kullanan kod:

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


System.Text.RegularExpressions kullanarak;
dhirschl

0

Kabul edilen cevap harika, ancak NULL değerleri hesaba katmıyor, bu nedenle çoğu senaryoda kullanılamaz hale getiriyor.

Bu, beni bu yardımcı yöntemleri kullanmaya itti. İlki OP'ye cevap verirken, diğerleri bunun tersini yapmak isteyenler için faydalı olabilir:

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

Ek bilgi için blogumdaki bu yazıyı okuyun .


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.