什么';这是用逗号作为小数分隔符验证数字的最佳方法


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

在Laravel应用程序中,我有一个表单,需要在该表单上使用逗号作为小数分隔符来验证数字。目前,它只适用于一点,因为我的验证规则是:

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

什么是最好的方法:

  • 是否保留规则并在验证前将逗号替换为点?是否有before_validation观察器或类似的东西
  • 是否生成自定义验证规则?例如french_numeric

Laravel在验证规则中支持regex模式,因此您可以使用给定的模式来匹配类似12,365.00的东西,并且建议在使用正则表达式作为规则时使用数组而不是管道

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

检查此链接。此外,如果您出于任何原因想要删除逗号,请检查此答案。

基于the Alpha的优秀答案,这里有一个代码片段,用于配置浮点验证。

将此片段添加到AppServiceProvider类中的boot()函数中(使用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;
});

env文件会有这两行:

APP_NUMBER_COMMA_SEPARATOR="."
APP_NUMBER_THOUSANDS_SEPARATOR=","

你的规则是这样的:

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

注意:我只是正确地逃离了.。如果您要使用regex语法中具有特殊含义的字符(如*或+),您也必须转义它们。

但是,由于像550*345,00 (550,345.00)57+44 (57.44)这样的浮点数没有意义,我忽略了这个问题。

亲切问候

如果其他人在从解决方案中检查正则表达式后遇到验证输入的数字大小的问题,我会在这里发布我的解决方案。我需要它来实现最大,尽管这与问题不同,但它可以很容易地适应最小

我创建了一个新的规则对象,如下所述:https://laravel.com/docs/8.x/validation#using-规则对象

注入参数的想法来自于这个答案:https://stackoverflow.com/a/62384976/11854580

toFloat方法是用户对https://www.php.net/manual/en/function.floatval.php

<?php
namespace App'Rules;
use App'Utils'NumberUtils;
use Illuminate'Contracts'Validation'Rule;
class NumericMaxForString implements Rule
{
    private $maxValue;
    /**
     * Create a new rule instance.
     *
     * @return void
     */
    public function __construct($maxValue)
    {
        $this->maxValue = $maxValue;
    }
    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        $numericValue = NumberUtils::toFloat($value);
        return $numericValue <= $this->maxValue;
    }
    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return 'The :attribute may not be greater than ' . $this->maxValue . '.';
    }
}