370
votes

I have a requirement to find and extract a number contained within a string.

For example, from these strings:

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

How can I do this?

30
Might the number be negative? If so, how would "Hello - how are you? -30" be handled?Jon Skeet
Hi John, No negative numbers in the datavan
Decimal numbers like 1.5? Exponential notation like 1.5E45?Tim Pietzcker
Similar (but not identical): stackoverflow.com/questions/1561273/…finnw
Why is no answer accepted here?Wiktor Stribiżew

30 Answers

90
votes

go through the string and use 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);
634
votes

\d+ is the regex for an integer number. So

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

returns a string containing the first occurrence of a number in subjectString.

Int32.Parse(resultString) will then give you the number.

222
votes

Here's how I cleanse phone numbers to get the digits only:

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

use regular expression ...

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!");
}
36
votes

What I use to get Phone Numbers without any punctuation...

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

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

// result: 7877636511
21
votes

Regex.Split can extract numbers from strings. You get all the numbers that are found in a string.

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

Output:

Number: 4 Number: 40 Number: 30 Number: 10

16
votes

Here's a Linq version:

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

Another simple solution using Regex You should need to use this

using System.Text.RegularExpressions;

and the code is

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

You can also try this

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

Just use a RegEx to match the string, then convert:

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

Here is another Linq approach which extracts the first number out of a string.

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

Examples:

string input = "123 foo 456"; // 123
string input = "foo 456";     // 456
string input = "123 foo";     // 123
10
votes
 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();
10
votes

if the number has a decimal points, you can use below

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

results :

"anything 876.8 anything" ==> 876.8

"anything 876 anything" ==> 876

"$876435" ==> 876435

"$876.435" ==> 876.435

Sample : https://dotnetfiddle.net/IrtqVt

9
votes

For those who want decimal number from a string with Regex in TWO line:

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

Same thing applys to float, long, etc...

9
votes

You can do this using String property like below:

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

which gives only number from string.

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

The question doesn't explicitly state that you just want the characters 0 to 9 but it wouldn't be a stretch to believe that is true from your example set and comments. So here is the code that does that.

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

Why you don't want to use Char.IsDigit() - Numbers include characters such as fractions, subscripts, superscripts, Roman numerals, currency numerators, encircled numbers, and script-specific digits.

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

Get all numbers in the string. So if you use for examaple '1 plus 2' it will get '12'.

5
votes

Extension method to get all positive numbers contained in a string:

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

If you want negative numbers as well simply modify this code to handle the minus sign (-)

Given this input:

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

The resulting numbers list will be:

[1989, 27, 2016]
4
votes

An interesting approach is provided here by Ahmad Mageed, uses Regex and StringBuilder to extract the integers in the order in which they appear in the string.

An example using Regex.Split based on the post by Ahmad Mageed is as follows:

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);
3
votes

Did the reverse of one of the answers to this question: How to remove numbers from string using Regex.Replace?

// Pull out only the numbers from the string using LINQ

var numbersFromString = new String(input.Where(x => x >= '0' && x <= '9').ToArray());

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

Here is my Algorithm

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

here is my solution

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

I have used this one-liner to pull all numbers from any string.

var phoneNumber = "(555)123-4567";
var numsOnly = string.Join("", new Regex("[0-9]").Matches(phoneNumber)); // 5551234567
0
votes

You will have to use Regex as \d+

\d matches digits in the given string.

0
votes
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"));
0
votes

Using @tim-pietzcker answer from above, the following will work for PowerShell.

PS C:\> $str = '1 test'
PS C:\> [regex]::match($str,'\d+').value
1
-3
votes

Based on the last sample I created a method:

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