Martin54
Martin54

Reputation: 1862

Regex - exclude "-" between numbers

In php I need to validate any number of positive and/or negative numbers from as input from textarea. Numbers can be float and will be separate by comma.

valid:

",,,66,,78.8,-89.8,,0.0,,3.14," or "," or "67,89,10,0876,,"

With help of regex101.com I've created this regex

^((-?\d+(\.\d+)?)|(,+))*$

and in php I have this code

if (preg_match("/^((-?\d+(\.\d+)?)|(,+))*$/", $text))
{
    echo "yes";
} else 
{
    echo "no";
}

And my problem is, that this regex also validate "-" and also extra "." among numbers.

This should be invalid:

",,67.8,89.8787,78-89,-8,07,,33.33.33,,,"

Can someone help how to improve this code?

Upvotes: 2

Views: 202

Answers (4)

CarlosCarucce
CarlosCarucce

Reputation: 3569

I modified you regex to ^(-?\d+(\.\d+)?,?)+$

Now it will validate strings like

"66,78.8,-89.8,0.0,3.14"

but not

",,,66,,78.8,-89.8,,0.0,,3.14,"

nor

"67,89,10,0876,,"

See if this works for your case.

Here is the test: https://regex101.com/r/Ivah2H/1

Upvotes: 0

Fanie Void
Fanie Void

Reputation: 329

I would try something like that:

$my_string = ",,67.8,89.8787,78-89,-8,07,,33.33.33,,,";
$array = explode(",", $my_string);

foreach ($array as $value){
    if (preg_match("[regex_to_create]", $value))
    {
        echo "yes";
    } else 
    {
        echo "no";
    }
}

I prefer to explode the string, as the regex can be tricky sometimes with long strings.

Upvotes: 1

revo
revo

Reputation: 48711

You could do this without Regular Expressions and with the help of is_numeric function:

$numbers = array_filter(explode(',', ',,67.8,-89.8787,7889,-8,07,,33.33.33,,,'));
$validate = true;
foreach ($numbers as $number) {
    if (!is_numeric($number)) {
        $validate = false;
        break;
    }
}

var_dump($validate); // false

Upvotes: 0

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626738

You may use

/^,*(-?\d*\.?\d+)?(?:,+\g<1>)*,*$/

See the regex demo.

Details

  • ^ - string start
  • ,* - 0+ commas
  • (-?\d*\.?\d+)? - Optional capturing group 1 matching a float number (note: you may keep your original \d+(?:\d+)? if you do not want to match .8 like floats)
  • (?:,+\g<1>)* - 0+ repetitions of
    • ,+ - 1+ commas
    • \g<1> - Capturing group 1 pattern (this is a subroutine call that is equal to (?1) and is used to repeat the first capturing group subpattern)
  • ,* - 0+ commas
  • $ - end of string.

Upvotes: 1

Related Questions