Rasso
Rasso

Reputation: 418

How to extract only floats(decimals) from a string that also includes integers

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

Answers (2)

Wiktor Stribiżew
Wiktor Stribiżew

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

PHP demo:

$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

arkascha
arkascha

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

Related Questions