Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the best way to validate numbers with comma as decimal separator?

In a Laravel app, I have a form on which I need to validate numbers with a comma as the decimal separator. For the moment, it only works with a point because my validation rule is:

$rules = [
    'amount' => 'numeric|min:0',
];

What’s the best method :

  • Keep the rule and replace comma with point before validation ? Is there a before_validation observer or something like this ?
  • Build a custom validation rule ? french_numeric for example ?
like image 782
Samuel De Backer Avatar asked Jul 13 '13 09:07

Samuel De Backer


People also ask

How do you validate decimal numbers?

It is compulsory to have a dot ('. ') in a text for a decimal value. Minus is used as a decimal number and can be a signed number also. Sign decimal numbers, like -2.3, -0.3 can have minus sign at first position only.

How do you make Excel recognize numbers with commas?

Re: EXCEL DOES NOT RECOGNIZE NUMBER WITH COMMAS FOR FORMULASSelect File > Options. Select Advanced in the navigation pane on the left. Clear the check box 'Use system separators' and change the decimal separator to a comma and the thousands separator to a point. Click OK.

Why do people use comma instead of decimal?

In the early 1700s, Gottfried Wilhelm Leibniz, a German polymath, proposed the dot as the symbol for multiplication. Therefore, most of Europe favored the comma as a decimal separator.

How do you use a comma with decimals?

And in countries where a point is used as a decimal separator, a comma is usually used to separate thousands. So, for example, twelve thousand five hundred with a decimal of five zero is written differently depending on the country: In the USA, Mexico, or the UK, it would be written: 12 500.50 or 12,500.50.


2 Answers

Laravel supports regex pattern in validation rule so you can use the given pattern to match something like 12,365.00 and it's recommended to use an array instead of pipe when using regular expressions as a rule

$rules = array('amount' => array('match:/^[0-9]{1,3}(,[0-9]{3})*\.[0-9]+$/'));

Check this link. Also, if you want to remove the commas for any reason then check this answer.

like image 139
The Alpha Avatar answered Nov 14 '22 23:11

The Alpha


Building on the excellent answer from The Alpha, here is a code snippet to make a float validation configurable.

Add this snippet to the boot() function in your AppServiceProvider class (tested with Laravel 5.4):

Validator::extend('float', function ($attribute, $value, $parameters, $validator) {
    $thousandsSeparator = env('APP_NUMBER_THOUSANDS_SEPARATOR') == '.' ? '\\' . env('APP_NUMBER_THOUSANDS_SEPARATOR') : env('APP_NUMBER_THOUSANDS_SEPARATOR');
    $commaSeparator = env('APP_NUMBER_COMMA_SEPARATOR') == '.' ? '\\' . env('APP_NUMBER_COMMA_SEPARATOR') : env('APP_NUMBER_COMMA_SEPARATOR');
    $regex = '~^[0-9]{1,3}(' . $thousandsSeparator . '[0-9]{3})*' . $commaSeparator . '[0-9]+$~';
    $validate = preg_match($regex, $value);

    if ($validate === 1) {
        return true;
    }

    return false;
});

Your .env-file would have those two lines:

APP_NUMBER_COMMA_SEPARATOR="."
APP_NUMBER_THOUSANDS_SEPARATOR=","

And your rule would look like this:

$rules = [
    'amount' => 'float|min:0',
];

Note: I'm only escaping the . correctly. If you are going to use charaters that have special meaning in regex syntax (like * or +) you have to escape them too.

But since a float number like 550*345,00 (550,345.00) or 57+44 (57.44) wouldn't make sense I've ignored this issue.

Kind regards

like image 25
Mario Haubenwallner Avatar answered Nov 14 '22 23:11

Mario Haubenwallner