400

I want to extract the digits from a string that contains numbers and letters like:

"In My Cart : 11 items"

I want to extract the number 11.

0

23 Answers 23

639

If you just want to filter everything other than the numbers out, the easiest is to use filter_var:

$str = 'In My Cart : 11 items';
$int = (int) filter_var($str, FILTER_SANITIZE_NUMBER_INT);
10
  • 66
    A dash before a number will be treated as a minus. Commented Nov 19, 2012 at 12:12
  • 50
    Not only before number. Any +/- will not be truncated. If you have xxx-yyy-24 you will get --24. You can use str_repleace(array('+','-'), '', $result) to delete both signs. Commented May 8, 2013 at 9:09
  • 4
    @imclickingmaniac you can simply do max(0,filter_var($str, FILTER_SANITIZE_NUMBER_INT)) instead using arrays and string replacements.
    – Eduard
    Commented May 24, 2013 at 2:48
  • 2
    using max() is also returning the minus sign in the strings, hope strreplace() is the option here. Thanks for tips. Commented Aug 29, 2013 at 13:58
  • 32
    abs((int) filter_var($str, FILTER_SANITIZE_NUMBER_INT));
    – MECU
    Commented Sep 11, 2015 at 16:46
407
$str = 'In My Cart : 11 12 items';
preg_match_all('!\d+!', $str, $matches);
print_r($matches);
7
  • 2
    How can I get my number in a simple variable and not in Array ?
    – Dali
    Commented Jun 8, 2011 at 12:15
  • 38
    $var = implode(' ', $matches[0]);
    – Gaurav
    Commented Jun 8, 2011 at 12:16
  • 3
    @Bizboss In a similar vein, try $newstr = preg_replace('!\d+!', '', $str);. It will strip out all the digits from your string. Example: $str = 'In My Cart : 11 12 items'; will output In My Cart : items.
    – Aether
    Commented Jun 8, 2011 at 13:02
  • $str = intval(preg_replace('@[^0-9]@', "", "In My Cart : 11 12 items"));
    – SpYk3HH
    Commented Apr 29, 2013 at 12:27
  • 8
    @eapo filter_var($str, FILTER_SANITIZE_NUMBER_INT); extracted digits, plus and minus sign. The regex extracted only digits!
    – PATROMO
    Commented Nov 9, 2016 at 9:36
380
preg_replace('/[^0-9]/', '', $string);

This should do better job!...

5
  • 13
    I like this because it returns a string, not an array like the examples with preg_match_all do, and I like it because I just want numbers, not a plus sign or dash, as the filter_var example does. Commented Feb 17, 2013 at 2:06
  • 48
    Becareful with this method: something like 'In My Car_Price : 500.00 will print : 50000
    – ErickBest
    Commented Jul 22, 2013 at 10:10
  • 25
    @ErickBest That's a good thing, considering the question was extract the numbers from a string -- a decimal point is not a number!
    – rybo111
    Commented Feb 1, 2014 at 17:30
  • 1
    Little simpler: preg_replace('/\D/', '', $string); Commented May 12, 2016 at 9:16
  • 2
    just use preg_replace('/[^0-9.]/','',$string) instead of you want to keep the . in ur number.
    – shamaseen
    Commented Feb 22, 2021 at 15:16
103

Using preg_replace:

$str = '(111) 111-1111';
$str = preg_replace('/\D/', '', $str);
echo $str;

Output: 1111111111

4
  • 4
    It's working great. It converts +387 (61) 634-783 string to 38761634783 directly. You don't have to take care of arrays like Gaurav's answer. Commented Jul 2, 2016 at 13:13
  • 1
    Definitly the best answer. sandbox.onlinephpfunctions.com/code/…
    – Steffan
    Commented Sep 29, 2018 at 11:07
  • I recommend the + quantifier to match longer matches / fewer replacements. Commented Feb 19, 2020 at 4:07
  • This answer appears to be answering a different question. The OP is only isolating one integer value from the string -- a number of items in a shopping cart. The understood scope of this page seems to have blown far out from what the OP has actually asked. This is the correct answer to a different question. Commented Nov 21, 2020 at 13:05
24

For floating numbers,

preg_match_all('!\d+\.?\d+!', $string ,$match);

Thanks for pointing out the mistake. @mickmackusa

4
  • It is actually wrong :) It should be '!\d*.?\d+!'
    – Yash
    Commented Aug 15, 2018 at 13:28
  • I would prefer to use ? as the quantifier of the literal dot. I wouldn't expect a float value to contain multiple decimal point symbols. Yash's commented pattern is wrong ironically. The dot needs a slash in front of it to make it literal. Commented Feb 19, 2020 at 4:40
  • 1
    The OP's sample text indicates that there is no potential for a float value -- it makes no sense to have partial items in a shopping cart. There is also only one integer value in the sample text, so employing preg_match_all() is overkill. This is, at best, the correct answer to a different question. Commented Nov 21, 2020 at 13:03
  • @mickmackusa You are absolutely right! I ended up on this question for a different use case and got an idea about how can I achieve it. The submitted answer was probably the solution I used at that time.
    – Yash
    Commented Nov 22, 2020 at 10:30
12

I do not own the credit for this, but I just have to share it. This regex will get numbers from a string, including decimal points/places, as well as commas:

/((?:[0-9]+,)*[0-9]+(?:\.[0-9]+)?)/

Cited from here:
php - regex - how to extract a number with decimal (dot and comma) from a string (e.g. 1,120.01)?

2
  • This isn't validating the string for a comma between sets of three whole numbers. ...the problem with copy-pasting someone else's pattern and not understanding/testing it. Commented Feb 19, 2020 at 4:44
  • Stack Overflow does not benefit when users copy-paste other Stack Overflow answers onto pages. If another Stack Overflow page contains the resolving advice for this page, then the correct behavior would be to use the hyperlink as a reason to close this page as a duplicate. Ultimately, this answer is simply not well suited to the OP's question. The OP will not possibly be isolating float values and we don't know if the there will be thousands separators. Commented Nov 21, 2020 at 13:00
11

You can use preg_match:

$s = "In My Cart : 11 items";
preg_match("|\d+|", $s, $m);
var_dump($m);
1
  • echo '<p>'.$m[0].'</p>';
    – Pathros
    Commented May 9, 2017 at 16:07
11

The top resource-friendly solutions for the following sample input string:

$string = "In My Cart : 11 items";
  1. Fastest: filter_varFilters a variable with a specified filter

    var_dump(
        filter_var($string, FILTER_SANITIZE_NUMBER_INT)
    ); // string(2) "11"
    
  2. Almost the fastest: str_replace — Replace all occurrences of the search string with the replacement string

    var_dump(
        str_replace(array('In My Cart : ',' item', 's'),"", $string)
    ); // string(2) "11"
    
  3. Fast enough: preg_replacePerform a regular expression search and replace

    var_dump(
        preg_replace("/[^0-9]/","",$string)
    ); // string(2) "11"
    

However

  • the simplicity of str_replace cause speed, but even limited use cases
  • preg_replace is much more versatile than str_replace or filter_var
  • instead is possible to use a function to specify what to replace using preg_replace_callback
  • with preg_replace_callback can do multiple replacements in one call
  • filter_var limited in sanitation options
1
  • filter_var($key, FILTER_SANITIZE_NUMBER_INT) solve the issue invoice_no[0] to 0 Commented Jun 2, 2023 at 16:52
10

Using preg_replace

$str = 'In My Cart : 11 12 items';
$str = preg_replace('/\D/', '', $str);
echo $str;
2
  • I recommend the + quantifier to match longer matches / fewer replacements. Commented Feb 19, 2020 at 4:09
  • Why would the OP want to form the string value 1112? What possible benefit could be drawn from this? Commented Nov 21, 2020 at 12:57
7
$value = '25%';

Or

$value = '25.025$';

Or

$value = 'I am numeric 25';
$onlyNumeric = filter_var($value, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);

This will return only the numeric value

1
  • Why would the OP possibly want to accommodate float values? How might the OP's users have a fraction of an item in their shopping cart? This appears to be the correct answer to a different question. Commented Nov 21, 2020 at 12:55
7
  1. Since there is only 1 numeric value to isolate in your string, I would endorse and personally use filter_var() with FILTER_SANITIZE_NUMBER_INT.

    Demo

    var_export(filter_var($string, FILTER_SANITIZE_NUMBER_INT));
    // '11'
    
  2. A whackier technique which works because there is only 1 numeric value AND the only characters that come before the integer are letters, colons, or spaces is to use ltrim() with a character mask then cast the remaining string as an integer.

    Demo

    var_export((int) ltrim($string, 'A..z: '));
                              // or ':..z ' (colon to z on ascii table and space)
    // 11
    
  3. Or another way to front-trim the string would be with strpbrk() and an all-digital character mask. This page dedicated to string functions which leverage character masks may give additional clarity.

    Demo

    var_export((int) strpbrk($string, '0123456789'));
    // 11
    
  4. If for some reason there was more than one integer value and you wanted to grab the first one, then regex would be a direct technique.

    Demo

    var_export(preg_match('/\d+/', $string, $m) ? $m[0] : '');
    // '11'
    

    Demo

    var_export(preg_replace('/\D*(\d+).*/', '$1', $string));
    // '11'
    

    Of course, if there is only one number in the string, as others have stated, preg_replace() can simply destroy non-digital characters.
    Demo

    var_export(preg_replace('/\D+/', '', $string));
    // '11'
    
  5. sscanf() is rather handy if you need to explicitly cast the numeric string as an integer (or float). If it is possible/unknown for the integer value to occur at the start of the string, then prepend a non-numeric character to the input string before scanning it. The following technique matches leading non-digits (and ignores them with * after the %), then matches the first occurring sequence of digits and casts the returned substring as an integer.

    Demo

    var_export(sscanf(' ' . $string, '%*[^0-9]%d')[0]);
    // 11
    

    To adapt this technique to extract a float value, just change the d to f. For more information on the (currently undocumented) assignment suppression feature of sscanf(), see this post.

6

You can use following function:

function extract_numbers($string)
{
   preg_match_all('/([\d]+)/', $string, $match);

   return $match[0];
}
2
  • There is no benefit to writing \d inside of a character class. Since you are accessing the fullstring match, there is no sense in writing a capture group into the pattern. Commented Feb 19, 2020 at 4:30
  • The OP only has one integer to isolate -- preg_match_all() is an inappropriate tool for the question being asked. This is (at best) a working answer to a different question. Commented Nov 21, 2020 at 12:57
5
preg_match_all('!\d+!', $some_string, $matches);
$string_of_numbers = implode(' ', $matches[0]);

The first argument in implode in this specific case says "separate each element in matches[0] with a single space." Implode will not put a space (or whatever your first argument is) before the first number or after the last number.

Something else to note is $matches[0] is where the array of matches (that match this regular expression) found are stored.

For further clarification on what the other indexes in the array are for see: http://php.net/manual/en/function.preg-match-all.php

1
  • For the OP's sample input, preg_match_all() is needless extra work and it creates an $matches array with unnecessary depth. This looks like the kind of question that has completely forgotten what the OP has asked in the question. Commented Nov 21, 2020 at 12:54
4

try this,use preg_replace

$string = "Hello! 123 test this? 456. done? 100%";
$int = intval(preg_replace('/[^0-9]+/', '', $string), 10);
echo $int;

DEMO

2
  • [^0-9] is more simply written as \D. Commented Feb 19, 2020 at 4:30
  • Why would the OP want to smash all of those values into a single value? What possible use is 123456100? Commented Nov 21, 2020 at 12:52
3

we can extract int from it like

$string = 'In My Car_Price : 50660.00';

echo intval(preg_replace('/[^0-9.]/','',$string));  # without number format   output: 50660
echo number_format(intval(preg_replace('/[^0-9.]/','',$string)));  # with number format  output :50,660

demo : http://sandbox.onlinephpfunctions.com/code/82d58b5983e85a0022a99882c7d0de90825aa398

1
  • Why are you accommodating decimal places? Did you read the OP's question? How might the OP's users have a fraction of an item in their shopping cart? Commented Nov 21, 2020 at 12:49
3

Follow this step it will convert string to number

$value = '$0025.123';
$onlyNumeric = filter_var($value, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
settype($onlyNumeric,"float");

$result=($onlyNumeric+100);
echo $result;

Another way to do it :

$res = preg_replace("/[^0-9.]/", "", "$15645623.095605659");
1
  • Did you read the question? How might the OP's users have a fraction of an item in their cart? Or did you just read other answers and forget to see what the OP actually asked? Commented Nov 21, 2020 at 12:48
2

other way(unicode string even):

$res = array();
$str = 'test 1234 555 2.7 string ..... 2.2 3.3';
$str = preg_replace("/[^0-9\.]/", " ", $str);
$str = trim(preg_replace('/\s+/u', ' ', $str));
$arr = explode(' ', $str);
for ($i = 0; $i < count($arr); $i++) {
    if (is_numeric($arr[$i])) {
        $res[] = $arr[$i];
    }
}
print_r($res); //Array ( [0] => 1234 [1] => 555 [2] => 2.7 [3] => 2.2 [4] => 3.3 ) 
1
  • I don't understand why this unexplained code would not use preg_split() instead of all of this convolution. Commented Sep 27, 2023 at 22:56
2

An alternative solution with sscanf:

$str = "In My Cart : 11 items";
list($count) = sscanf($str, 'In My Cart : %s items');
1
  • This is a very sensible technique for this specific case (where the non-numeric portion of the string is predictably static). It might be useful for researchers to understand that %d can also be used for casting the numeric substring as integer type data. 3v4l.org/lLTXv @salathe mentioned this technique back in 2011, but was convinced by the OP to delete the answer on the grounds that the full string did not have a reliably static format. (The variability of the text should have been clarified by the OP.) Commented Jul 23, 2021 at 7:21
-1

If you don't know which format the number is? int or floating, then use this :

$string = '$125.22';

$string2 = '$125';

preg_match_all('/(\d+.?\d+)/',$string,$matches); // $matches[1] = 125.22

preg_match_all('/(\d+.?\d+)/',$string2,$matches); // $matches[1] = 125
1
  • The capture groups are unnecessary because you are capturing the fullstring match -- effectively doubling the size of the matches array for no benefit. If the input strings are merely prepended with a $, then just use ltrim($string, '$'). Commented May 6, 2022 at 1:26
-2

Depending on your use case, this might also be an option:

$str = 'In My Cart : 11 items';
$num = '';

for ($i = 0; $i < strlen($str); $i++) {

    if (is_numeric($str[$i])) {
        $num .= $str[$i];
    }
}

echo $num; // 11

Though I'd agree a regex or filter_var() would be more useful in the stated case.

-2

for utf8 str:

function unicodeStrDigits($str) {
    $arr = array();
    $sub = '';
    for ($i = 0; $i < strlen($str); $i++) { 
        if (is_numeric($str[$i])) {
            $sub .= $str[$i];
            continue;
        } else {
            if ($sub) {
                array_push($arr, $sub);
                $sub = '';
            }
        }
    }

    if ($sub) {
        array_push($arr, $sub); 
    }

    return $arr;
}
1
  • This is definitely not utf8 ready because you are not using mb_ functions and you are using [offset] syntax to access each byte in the string. This unexplained answer is "no bueno". Commented May 6, 2022 at 1:28
-2

This functions will also handle the floating numbers

$str = "Doughnuts, 4; doughnuts holes, 0.08; glue, 3.4";
$str = preg_replace('/[^0-9\.]/','-', $str);
$str = preg_replace('/(\-+)(\.\.+)/','-', $str);
$str = trim($str, '-');
$arr = explode('-', $str);
1
  • Introducing hyphens to this process is entirely unnecessary. This answer also lacks an explanation of how it works and why you feel it is a good idea. Commented Feb 19, 2020 at 4:33
-3

This script creates a file at first , write numbers to a line and changes to a next line if gets a character other than number. At last, again it sorts out the numbers to a list.

string1 = "hello my name 12 is after 198765436281094and14 and 124de"
f= open("created_file.txt","w+")
for a in string1:
    if a in ['1','2','3','4','5','6','7','8','9','0']:
        f.write(a)
    else:
        f.write("\n" +a+ "\n")
f.close()


#desired_numbers=[x for x in open("created_file.txt")]

#print(desired_numbers)

k=open("created_file.txt","r")
desired_numbers=[]
for x in k:
    l=x.rstrip()
    print(len(l))
    if len(l)==15:
        desired_numbers.append(l)


#desired_numbers=[x for x in k if len(x)==16]
print(desired_numbers)
1
  • 1
    This questions seems to be a PHP related question.
    – ALZlper
    Commented Nov 14, 2020 at 19:15

Not the answer you're looking for? Browse other questions tagged or ask your own question.