404

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

646

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);
Sign up to request clarification or add additional context in comments.

10 Comments

A dash before a number will be treated as a minus.
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.
@imclickingmaniac you can simply do max(0,filter_var($str, FILTER_SANITIZE_NUMBER_INT)) instead using arrays and string replacements.
using max() is also returning the minus sign in the strings, hope strreplace() is the option here. Thanks for tips.
abs((int) filter_var($str, FILTER_SANITIZE_NUMBER_INT));
|
408

You can use regex to extract all numeric characters from a string:

$str = 'In My Cart : 11 12 items';
preg_match_all('!\d+!', $str, $matches);
print_r($matches);

You can then concatenate them to make your integer:

$integer = implode('', $matches[0]);

7 Comments

How can I get my number in a simple variable and not in Array ?
$var = implode(' ', $matches[0]);
@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.
$str = intval(preg_replace('@[^0-9]@', "", "In My Cart : 11 12 items"));
@eapo filter_var($str, FILTER_SANITIZE_NUMBER_INT); extracted digits, plus and minus sign. The regex extracted only digits!
|
383
preg_replace('/[^0-9]/', '', $string);

This should do better job!...

5 Comments

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.
Becareful with this method: something like 'In My Car_Price : 500.00 will print : 50000
@ErickBest That's a good thing, considering the question was extract the numbers from a string -- a decimal point is not a number!
Little simpler: preg_replace('/\D/', '', $string);
just use preg_replace('/[^0-9.]/','',$string) instead of you want to keep the . in ur number.
103

Using preg_replace:

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

Output: 1111111111

4 Comments

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.
Definitly the best answer. sandbox.onlinephpfunctions.com/code/…
I recommend the + quantifier to match longer matches / fewer replacements.
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.
24

For floating numbers,

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

Thanks for pointing out the mistake. @mickmackusa

4 Comments

It is actually wrong :) It should be '!\d*.?\d+!'
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.
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.
@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.
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 Comments

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.
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.
11

You can use preg_match:

$s = "In My Cart : 11 items";
preg_match("|\d+|", $s, $m);
var_dump($m);

1 Comment

echo '<p>'.$m[0].'</p>';
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 Comment

filter_var($key, FILTER_SANITIZE_NUMBER_INT) solve the issue invoice_no[0] to 0
10

Using preg_replace

$str = 'In My Cart : 11 12 items';
$str = preg_replace('/\D/', '', $str);
echo $str;

2 Comments

I recommend the + quantifier to match longer matches / fewer replacements.
Why would the OP want to form the string value 1112? What possible benefit could be drawn from this?
8
  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.

Comments

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 Comment

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.
6

You can use following function:

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

   return $match[0];
}

2 Comments

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.
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.
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 Comment

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.
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 Comments

[^0-9] is more simply written as \D.
Why would the OP want to smash all of those values into a single value? What possible use is 123456100?
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 Comment

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?
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 Comment

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?
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 Comment

I don't understand why this unexplained code would not use preg_split() instead of all of this convolution.
2

An alternative solution with sscanf:

$str = "In My Cart : 11 items";
list($count) = sscanf($str, 'In My Cart : %s items');

1 Comment

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.)
-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 Comment

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, '$').
-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.

Comments

-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 Comment

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".
-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 Comment

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.
-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 Comment

This questions seems to be a PHP related question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.