skip to Main Content

My regex doesn’t work as expected when I run my code, but when I test it on a website the regex does exactly as expected. See my function:

function checkDecimais($numero){

            if($numero > 0){
                preg_match('/^([0]+).([0]*)([1-9])/', $numero, $matches);

                if(isset($matches[2])){
                    return strlen($matches[2]);
                }else{
                    return 0;  
                }

            }else{
                return 0;
            }
}

If I call it like this: checkDecimais(0.0009) it works and returns the number 3, as it has 3 decimal zero digits. However, if I call it like this: checkDecimais(0.00009) , it stops working and returns 0, because my regex is only taking up to 3 zero digits and ignoring when there are more than three digits?

If I change it to string checkDecimais('0.0009') , it works, however I’m giving it numbers and I can’t understand why it doesn’t work.

Can anybody help me ?

I’ve already tried using other regex, but they all have the same problem, it only takes the first 3 zeros when the data is of type number.

2

Answers


  1. Echoing $numero will reveal the problem:

    9.0E-5
    

    When you use a number, in a function that expects a string, PHP has to convert it. PHP’s default way of doing so seems to use scientific notation for 0.00009, but not for 0.0009. The converted form of 0.00009 is "9.0E-5", which does not match your regular expression because it does not start with a zero.

    Instead, pas a string as your argument to your regular expression:

    echo checkDecimais("0.00009");
    

    Or, convert a number to a string explicitly using a format of your choice:

    $numero = sprintf("%f", 0.00009);
    
    Login or Signup to reply.
  2. Regular Expression match characters in strings. You do not use strict types so PHP will cast the number into a string automatically. For a 0.00009 this will result in the scientific notation 9.0E-5.

    You can use number_format() to specify how the number is formatted into a string.

    $data = [
        0.009,
        0.0009,
        0.00009,
    ];
    
    foreach ($data as $numero) {
        echo $numero, ' - ', number_format($numero, 10, '.', ''), ' - ', checkDecimais($numero), "n";
    }
    
    
    function checkDecimais(float $numero): int {
    
        $subject = number_format($numero, 10, '.', '');
        if ($numero > 0) {
            preg_match('/^([0]+).([0]*)([1-9])/', $subject, $matches);
    
            if(isset($matches[2])){
                return strlen($matches[2]);
            }else{
                return 0;  
            }
    
        } else {
            return 0;
        }
    }
    

    Output:

    0.009 - 0.0090000000 - 2
    0.0009 - 0.0009000000 - 3
    9.0E-5 - 0.0000900000 - 4
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search