Bir dizeden sayı bulma ve çıkarma


319

Bulmak ve bir dize içinde bulunan bir sayı ayıklamak için bir gereksinim var.

Örneğin, şu dizelerden:

string test = "1 test"
string test1 = " 1 test"
string test2 = "test 99"

Bunu nasıl yapabilirim?


2
Sayı negatif olabilir mi? Eğer öyleyse, "Merhaba - nasılsın? -30" nasıl ele alınır?
Jon Skeet

Merhaba John, Verilerde negatif sayı yok
minibüs

4
Ondalık sayılar 1.5? Üstel gösterim gibi 1.5E45mi?
Tim Pietzcker

Benzer (ancak aynı değil): stackoverflow.com/questions/1561273/…
finnw

3
Burada neden cevap kabul edilmiyor?
Wiktor Stribiżew

Yanıtlar:


63

ip üzerinden git ve kullan Char.IsDigit

string a = "str123";
string b = string.Empty;
int val;

for (int i=0; i< a.Length; i++)
{
    if (Char.IsDigit(a[i]))
        b += a[i];
}

if (b.Length>0)
    val = int.Parse(b);

15
@Thomas: Bu kod çalışmaz, bununla sonuçlanır b == "System.Linq.Enumerable..". Doğru (ve hatta daha basit)b = String.Join("", a.Where(char.IsDigit))
BlueRaja - Danny Pflughoeft

1
İyi bir nokta, bana yorumda yazdığım kodu test etmemeyi öğretecek! Ayrıca yapıcıyı kullanarak bir char dizisinden dize de yapabilirsiniz new string(char[]).
Thomas

1
Regex çok daha iyi bir iş çıkarıyor.
Jason Kelley

@BlueRaja - Danny Pflughoeft Neden oyunuzu verebilmeniz için yorumunuzu doğru bir cevap
yapmıyorsunuz

NOT: Dize birden çok sayı içeriyorsa, bu yanıt hepsini tek bir sayı olarak çalıştırır. Örneğin "a12bcd345", "12345" ile sonuçlanır. (Bu hedefe bağlı olarak istenebilir veya istenmeyebilir.) Bu, yukarıda belirtilen durum için "12" döndürecek olan en çok oy alan Regex çözümünden farklıdır. Bu, "555-111-2222" telefon numaraları gibi durumlar için önemlidir.
ToolmakerSteve

546

\d+bir tamsayı için normal ifadedir. Yani

//System.Text.RegularExpressions.Regex
resultString = Regex.Match(subjectString, @"\d+").Value;

içindeki bir sayının ilk oluşumunu içeren bir dize döndürür subjectString.

Int32.Parse(resultString) size numarayı verecektir.


10
destek negatif sayılara şunu kullanabilirsiniz Regex.Match(subjectString, @"-?\d+").Valueyerine
Jon Listesini

45
Bu cevap tamamlanmamıştır (C # ile). Dizede sadece ilk sayıyı alıyor. Eşleşmeler üzerinde itaat etmeniz gerekir: sonuçString = string.Join (string.Empty, Regex.Matches (SubjectString, @ "\ d +"). OfType <Match> () .Select (m => m.Value));
Markus

8
@Markus: Soru " bir dize içinde bulunan bir sayı çıkarmak gerekir " ve tüm örnekler dizede mevcut tek bir sayı gösterir. Tek bir öğe üzerinde yineleme yapmak yararlı değildir.
Tim Pietzcker

2
@ayman: Oh, virgül binlerce ayırıcı mı? Bu, çok daha karmaşık bir regex gerektirecektir - bu ayrı bir soruda ele alınmalıdır. Mükemmel bir başlangıç ​​noktası, .NET'in normal ifade motorundaki bölümleri de içeren Regular-Expressions.info'dur .
Tim Pietzcker

5
@DavidSopko: Sen neden bahsediyorsun? Orijinal soru, başlıkta ve soru gövdesinde bir dizeden tek bir sayı çıkarmak için bir yol istedi. Orijinal yazarın dışındaki kişiler tarafından soruyu daha sonra (cevabımdan bir yıl sonra ve sonra) yapılan düzenlemeler başlığı "sayılar" olarak değiştirdi. Herhangi bir şey varsa, bu hatalı düzenleme geri alınmalıdır.
Tim Pietzcker

180

Sadece rakamları almak için telefon numaralarını nasıl temizlerim:

string numericPhone = new String(phone.Where(Char.IsDigit).ToArray());

31
string numericPhone =new String(phone.Where(Char.IsDigit).ToArray());
Damith

1
çok zarif bir çözüm ..
Linq

1
Tamsayılar için güzel bir çözüm! Ondalık bir sayı olmadığı için ondalık bir sayı ayrıştırmaya çalışıyorsanız bunun işe yaramayacağını unutmayın.
Elijah Lofgren

40

düzenli ifade kullan ...

Regex re = new Regex(@"\d+");
Match m = re.Match("test 66");

if (m.Success)
{
    Console.WriteLine(string.Format("RegEx found " + m.Value + " at position " + m.Index.ToString()));
}
else
{
    Console.WriteLine("You didn't enter a string containing a number!");
}

33

Noktalamadan Telefon Numaralarını almak için kullandığım şey ...

var phone = "(787) 763-6511";

string.Join("", phone.ToCharArray().Where(Char.IsDigit));

// result: 7877636511

18

Regex.Split, dizelerden sayı çıkarabilir. Bir dizede bulunan tüm sayıları alırsınız.

string input = "There are 4 numbers in this string: 40, 30, and 10.";
// Split on one or more non-digit characters.
string[] numbers = Regex.Split(input, @"\D+");
foreach (string value in numbers)
{
    if (!string.IsNullOrEmpty(value))
    {
    int i = int.Parse(value);
    Console.WriteLine("Number: {0}", i);
    }
}

Çıktı:

Sayı: 4 Sayı: 40 Sayı: 30 Sayı: 10


16

İşte bir Linqsürüm:

string s = "123iuow45ss";
var getNumbers = (from t in s
                  where char.IsDigit(t)
                  select t).ToArray();
Console.WriteLine(new string(getNumbers));

14
basitçe ne olacak "123iuow45ss".AsEnumerable().Where(char.IsDigit)?
Ilya Ivanov

2
from t .. select tArtıklığı sevmiyorum , ama neyse, şerefe.
Ilya Ivanov

14

Regex kullanarak başka bir basit çözüm Bunu kullanmanız gerekir

using System.Text.RegularExpressions;

ve kod

string var = "Hello3453232wor705Ld";
string mystr = Regex.Replace(var, @"\d", "");
string mynumber = Regex.Replace(var, @"\D", "");
Console.WriteLine(mystr);
Console.WriteLine(mynumber);

12

Bunu da deneyebilirsin

string.Join(null,System.Text.RegularExpressions.Regex.Split(expr, "[^\\d]"));

güzel ama orijinal dizedeki sayılar arasında boşluk varsa, o zaman size her iki sayının katıldığı 1 büyük birleştirilmiş dize verecektir (boşluk yok)
Mohammad Zekrallah

11

Dizeyi eşleştirmek için bir RegEx kullanın, sonra dönüştürün:

Match match = Regex.Match(test , @"(\d+)");
if (match.Success) {
   return int.Parse(match.Groups[1].Value);
}

9

İşte Linqbir dizeden ilk sayıyı çıkaran başka bir yaklaşım.

string input = "123 foo 456";
int result = 0;
bool success = int.TryParse(new string(input
                     .SkipWhile(x => !char.IsDigit(x))
                     .TakeWhile(x => char.IsDigit(x))
                     .ToArray()), out result);

Örnekler:

string input = "123 foo 456"; // 123
string input = "foo 456";     // 456
string input = "123 foo";     // 123

9

İsteyenler için ondalık bir dize numarayı Regex içinde İKİ hattı:

decimal result = 0;
decimal.TryParse(Regex.Match(s, @"\d+").Value, out result);

Aynı şey şamandıra , uzun , vb için de geçerlidir.


9
 string input = "Hello 20, I am 30 and he is 40";
 var numbers = Regex.Matches(input, @"\d+").OfType<Match>().Select(m => int.Parse(m.Value)).ToArray();

1
Bu bana istediğimi verdi, dize içinde birden çok sayı dizisi olan en iyi cevap. Keşke virgül sayılardan (bin ayırıcı) göz ardı edebilseydi, bu mükemmel olurdu! :-)
Sagar

9

Bunu Stringaşağıdaki gibi bir özellik kullanarak yapabilirsiniz :

 return new String(input.Where(Char.IsDigit).ToArray()); 

dizeden yalnızca sayı verir.


7
var match=Regex.Match(@"a99b",@"\d+");
if(match.Success)
{
    int val;
    if(int.TryParse(match.Value,out val))
    {
        //val is set
    }
}

7

Soru, 0 ile 9 arasındaki karakterleri istediğinizi açıkça belirtmez, ancak örnek kümeniz ve yorumlarınızda bunun doğru olduğuna inanmak zor olmaz. İşte bunu yapan kod.

        string digitsOnly = String.Empty;
        foreach (char c in s)
        {
            // Do not use IsDigit as it will include more than the characters 0 through to 9
            if (c >= '0' && c <= '9') digitsOnly += c;
        }

Neden Char.IsDigit () işlevini kullanmak istemiyorsunuz - Sayılar, kesirler, abonelikler, üst simgeler, Romen rakamları, para birimi numaraları, çevrelenmiş sayılar ve komut dosyasına özgü rakamlar gibi karakterleri içerir.


6
var outputString = String.Join("", inputString.Where(Char.IsDigit));

Dizedeki tüm sayıları alın. Yani '1 artı 2' sınavı için kullanırsanız, '12' alırsınız.


5

Bir dizedeki tüm pozitif sayıları almak için genişletme yöntemi :

    public static List<long> Numbers(this string str)
    {
        var nums = new List<long>();
        var start = -1;
        for (int i = 0; i < str.Length; i++)
        {
            if (start < 0 && Char.IsDigit(str[i]))
            {
                start = i;
            }
            else if (start >= 0 && !Char.IsDigit(str[i]))
            {
                nums.Add(long.Parse(str.Substring(start, i - start)));
                start = -1;
            }
        }
        if (start >= 0)
            nums.Add(long.Parse(str.Substring(start, str.Length - start)));
        return nums;
    }

Negatif sayılar da istiyorsanız, eksi işaretini (- )

Bu girdi verildiğinde:

"I was born in 1989, 27 years ago from now (2016)"

Ortaya çıkan sayılar listesi:

[1989, 27, 2016]

5

sayının ondalık noktası varsa, aşağıda kullanabilirsiniz

using System;
using System.Text.RegularExpressions;

namespace Rextester
{
    public class Program
    {
        public static void Main(string[] args)
        {
            //Your code goes here
            Console.WriteLine(Regex.Match("anything 876.8 anything", @"\d+\.*\d*").Value);
            Console.WriteLine(Regex.Match("anything 876 anything", @"\d+\.*\d*").Value);
            Console.WriteLine(Regex.Match("$876435", @"\d+\.*\d*").Value);
            Console.WriteLine(Regex.Match("$876.435", @"\d+\.*\d*").Value);
        }
    }
}

Sonuçlar :

"bir şey 876.8 bir şey" ==> 876.8

"her şey 876 her şey" ==> 876

"876435 $" ==> 876435

"876.435 $" ==> 876.435

Örnek: https://dotnetfiddle.net/IrtqVt


1
Bu cevap için çok teşekkür ederim. C # ve VS2017 kullanıyorum ve değeri nasıl bulacağım anlamaya çalışıyordu. Cevabınız için tekrar teşekkür ederim.
kabarcıklar


2
  string verificationCode ="dmdsnjds5344gfgk65585";
            string code = "";
            Regex r1 = new Regex("\\d+");
          Match m1 = r1.Match(verificationCode);
           while (m1.Success)
            {
                code += m1.Value;
                m1 = m1.NextMatch();
            }

Bu Kod, bir dizedeki tüm tamsayı değerlerini bulmak için kullanılır.
Manoj Gupta

Cevaba ayrı bir yorum olarak göndermekten çok, cevaba doğrudan bir açıklama eklemek daha iyidir. Yorumlar her zaman hemen görünmez.
John Dvorak

2

Burada ilginç bir yaklaşım var Ahmad Mageed tarafından sağlanır, tam sayıları dizede göründükleri sırayla çıkarmak için Regex ve stringbuilder'ı kullanır.

Ahmad Mageed'in gönderisine dayanan Regex.Split kullanan bir örnek aşağıdaki gibidir:

var dateText = "MARCH-14-Tue";
string splitPattern = @"[^\d]";
string[] result = Regex.Split(dateText, splitPattern);
var finalresult = string.Join("", result.Where(e => !String.IsNullOrEmpty(e)));
int DayDateInt = 0;

int.TryParse(finalresult, out DayDateInt);

2

İşte Algoritmam

    //Fast, C Language friendly
    public static int GetNumber(string Text)
    {
        int val = 0;
        for(int i = 0; i < Text.Length; i++)
        {
            char c = Text[i];
            if (c >= '0' && c <= '9')
            {
                val *= 10;
                //(ASCII code reference)
                val += c - 48;
            }
        }
        return val;
    }

1

işte benim çözümüm

string var = "Hello345wor705Ld";
string alpha = string.Empty;
string numer = string.Empty;
foreach (char str in var)
{
    if (char.IsDigit(str))
        numer += str.ToString();
    else
        alpha += str.ToString();
}
Console.WriteLine("String is: " + alpha);
Console.WriteLine("Numeric character is: " + numer);
Console.Read();

0

Regex'i şu şekilde kullanmanız gerekecek: \d+

\d verilen dizedeki rakamlarla eşleşir.


0
static string GetdigitFromString(string str)
    {
        char[] refArray = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
        char[] inputArray = str.ToCharArray();
        string ext = string.Empty;
        foreach (char item in inputArray)
        {
            if (refArray.Contains(item))
            {
                ext += item.ToString();
            }
        }
        return ext;
    }

0
string s = "kg g L000145.50\r\n";
        char theCharacter = '.';
        var getNumbers = (from t in s
                          where char.IsDigit(t) || t.Equals(theCharacter)
                          select t).ToArray();
        var _str = string.Empty;
        foreach (var item in getNumbers)
        {
            _str += item.ToString();
        }
        double _dou = Convert.ToDouble(_str);
        MessageBox.Show(_dou.ToString("#,##0.00"));


-3

Son örneğe dayanarak bir yöntem oluşturdum:

private string GetNumberFromString(string sLongString, int iLimitNumbers)
{
    string sReturn = "NA";
    int iNumbersCounter = 0;
    int iCharCounter = 0; 

    string sAlphaChars = string.Empty;
    string sNumbers = string.Empty;
    foreach (char str in sLongString)
    {
        if (char.IsDigit(str))
        {
            sNumbers += str.ToString();
            iNumbersCounter++;
            if (iNumbersCounter == iLimitNumbers)
            {
                return sReturn = sNumbers;
            }
        }
        else
        {
            sAlphaChars += str.ToString();
            iCharCounter++;
            // reset the counter 
            iNumbersCounter = 0; 
        }
    }
    return sReturn;
}
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.