user6972
user6972

Reputation: 911

PHP Regex how to capture floating point numbers that do not have a letter at the end

I'm using preg_match_all and I want to capture the floating point numbers that do not have a letter following them.

For example

-20.4a 110b 139 31c 10.4

Desired

[0] => Array
    (
        [0] => 139
        [1] => 10.4
    )

I've tried was able do to the opposite using this pattern:

/\d+(.\d+)?(?=[a-z])/i

which captures the numbers with letters that you can see in this demo. But I can't figure out how to capture the numbers that have no trailing letters.

Upvotes: 1

Views: 543

Answers (3)

Toto
Toto

Reputation: 91385

Use negative lookahead:

/\d+(\.\d+)?(?![a-z])/i

But it is not sufficient, you have to exclude also digit and dot:

/\d+(?:\.\d+)?(?![a-z\d.])/i

PHP:

$string = '-20.4a 110b 139 31c 10.4';
preg_match_all('/\d+(?:\.\d+)?(?![a-z\d.])/', $string, $match);
print_r($match);

Output:

Array
(
    [0] => Array
        (
            [0] => 139
            [1] => 10.4
        )

)

Upvotes: 2

anubhava
anubhava

Reputation: 785128

You can use this regex with a positive lookahead:

[+-]?\b\d*\.?\d+(?=\h|$)

RegEx Demo

(?=\h|$) asserts presence of a horizontal white space or end of line after matched number.

Alternatively you can use this regex with a possessive quantifier:

[+-]?\b\d*\.?\d++(?![.a-zA-Z])

RegEx Demo 2

Upvotes: 1

Sebastian Proske
Sebastian Proske

Reputation: 8413

There are a few approaches one can take here.

Atomic group matching and a negative lookahead or word boundary:

(?>\d+(?:\.\d+)?)(?![a-z])
(?>\d+(?:\.\d+)?)\b

Using a negative lookahead that also denies a dot and numbers:

\d+(?:\.\d+)?(?![a-z.\d])

Positive lookahead to a space (seems to be the separator in here) or the end of string

\d+(?:\.\d+)?(?=\s|$)

Upvotes: 1

Related Questions