Reputation: 418
I can't find the appropriate regex to extract only floats from a string. Consider the following string:
$string = "8x2.1 3x2";
I want to extract 2.1, I tried the following but this gives me integers and floats:
preg_match_all('/[0-9,]+(?:\.[0-9]*)?/', $string, $matches);
i then tried using is_float
to check for floats but this also returns the integers for some reason. Any ideas?
thanks
Upvotes: 2
Views: 1140
Reputation: 627336
Your regex matches float and integers, and even strings consisting of just commas.
[0-9,]+
- 1 or more digits or ,
(?:\.[0-9]*)?
- one or zero sequences of .
+ zero or more digits.You need
/\d+\.\d+/
That will match 1+ digits, .
and 1+ digits.
Or, to also match negative and positive floats, add an optional -
at the beginning:
/-?\d+\.\d+/
Details
-?
- one or zero hyphens (?
means match one or zero occurrences)\d+
- one or more digits (+
means match one or more occurrences, \d
matches a digit char)\.
- a literal dot (since a dot in a regex is a special metacharacter, it should be escaped to denote a literal dot)\d+
- one or more digits$string = "8x2.1 3x2";
preg_match_all('/\d+\.\d+/', $string, $matches);
print_r($matches[0]);
// => Array ( [0] => 2.1 )
A bonus regex that will also match only float numbers with optional exponent (a variant of the regex at regular-expressions.info):
/[-+]?\d+\.\d+(?:e[-+]?\d+)?/i
Here, you can see that an optional +
or -
is matched first ([-+]?
), then the same pattern as above is used, then comes an optional non-capturing group (?:...)?
that matches 1 or 0 occurrences of the following sequence: e
or E
(since /i
is a case insensitive modifier), [-+]?
matches an optional +
or -
, and \d+` matches 1+ digits.
Upvotes: 3
Reputation: 42959
Consider this simple example:
<?php
$input = "8x2.1 3x2";
preg_match('/\d+\.\d+/', $input, $tokens);
print_r($tokens);
Matches "one or more digits, followed by exactly one full stop and again one or more digits".
The output obviously is:
Array
(
[0] => 2.1
)
Upvotes: 6