ChatGPT解决这个技术问题 Extra ChatGPT

Extract a single (unsigned) integer from a string

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.


B
Bruno Viera Guerra

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

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));
G
Gaurav
$str = 'In My Cart : 11 12 items';
preg_match_all('!\d+!', $str, $matches);
print_r($matches);

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.
thi is not a resource friendly way. use preg_replace("/[^0-9]/","",$string); or filter_var($str, FILTER_SANITIZE_NUMBER_INT);
@eapo filter_var($str, FILTER_SANITIZE_NUMBER_INT); extracted digits, plus and minus sign. The regex extracted only digits!
s
simhumileco
preg_replace('/[^0-9]/', '', $string);

This should do better job!...


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.
b
bob jomes

Using preg_replace:

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

Output: 1111111111


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.
Y
Yash

For floating numbers,

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

Thanks for pointing out the mistake. @mickmackusa


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.
C
Community

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


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.
D
Dmitri Gudkov

You can use preg_match:

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

echo '<p>'.$m[0].'</p>';
H
Hariadi

Using preg_replace

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

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?
R
Rakesh
$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


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.
R
Ross Allen

You can use following function:

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

   return $match[0];
}

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.
e
eapo

The top resource-friendly solutions

<?php
    var $string = "In My Cart : 11 items";
?>

1. Fastest: filter_var — Filters a variable with a specified filter

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

<?php
    str_replace(array('In My Cart : ',' item', 's'),"", $string); // string(2) "11"
?>

3. Fast enough: preg_replace — Perform a regular expression search and replace

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


B
Bradley Kovacs
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


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.
D
Dave

try this,use preg_replace

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

DEMO


[^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?
u
user889030

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


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?
j
jewelhuq

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

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?
m
mickmackusa

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.

echo filter_var($string, FILTER_SANITIZE_NUMBER_INT);

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

$string = "In My Cart : 11 items";
echo (int)ltrim($string, 'A..z: ');
// 11

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

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

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_dump(sscanf(' ' . $string, '%*[^0-9]%d')[0]);

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.


M
Mehrdad

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 ) 

F
Francesco Terenzani

An alternative solution with sscanf:

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

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.)
k
kasimir

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.


M
Mehrdad

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

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".
S
Sajjad Hossain Sagor

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

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

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

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.
C
ChrisF

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)

This questions seems to be a PHP related question.