使用正则表达式

时间:2018-05-25 09:26:40

标签: php laravel validation laravel-5.6 error-messaging

好吧,我在这里遇到了一个非常困难的局面,我想我要么已经缺席了已经存在的关键事件,要么Laravel目前还没有提供实现这一目标的方法。 我想指定一个自定义验证错误消息,其中包含我想在消息中替换的自定义占位符。问题在于:我正在使用regex验证规则,Laravel documentation明确指出,应该更好地传递给数组,以避免不必要的分隔符行为。情况如下:我想指定一个用于验证name.regex的全局多语言消息,我已经这样做了:

'custom' => [
    'name' => [
        'regex' => 'The :attribute must corespond to the given format: :format!'
    ]
]

正如您所看到的,我在该消息中放置了一个自定义占位符:format,因为对于不同类的name属性,我将匹配不同的正则表达式。因此,我希望能够在验证过程中输入每个给定正则表达式的自定义人类可读描述(作为参数)。 所以我在我的控制器中执行以下操作:

$input = Input::all();
$validator = Validator::make($input, [
        'name' => ['required', 'regex:/^\p{Lu}\p{L}+ \p{Lu}\p{L}+$/u']
    ]);

我的Validator::replacer()中还有一个AppServiceProvider.php方法应该替换邮件中的:format占位符:

Validator::replacer('regex', function($message, $attr, $rule, $parameters){
        return str_replace(':format', "I would like to be able to somehow retrieve the custom format description here, but using \$parameters[] is not an option", $message);
    });

regex验证规则的问题是我真的不允许在验证器中向它传递参数,例如:

$validator = Validator::make($input, [
        'name' => ['required', 'regex:/^\p{Lu}\p{L}+ \p{Lu}\p{L}+$/u,Thats my custom validator format description']
    ]);

因为它完全混淆了正则表达式(应该是这样)。因此,我无法在replacer()中使用$ parameters 1 $来替换占位符。此外,将整个句子作为验证规则的逗号分隔参数传递将非常不方便。所以这个概念不符合需要。

:format值将是动态的,并且会在不同类的name字段要求中严重变化,因此我确实需要将动态多语言描述设置为当前验证程序实例的属性。我想也许最方便的情况可能就是这样:

$validator = Validator::make($input, [
        'name' => ['required', 'regex:/^\p{Lu}\p{L}+ \p{Lu}\p{L}+$/u', 'format:Current name requirements described here.']
    ]);

并且Laravel以某种方式知道:format应该被该实例的消息中的当前规则替换。我想过明确地将这个附加参数添加为验证规则,然后再进行管理,但我实际上无法实现跨规则连接(换句话说,获取新format规则的参数和在regex规则中使用它。 我真的不知道如何处理这个问题,任何帮助将不胜感激。提前谢谢!

P.S。我知道每次都可以指定整个消息:

$input = Input::all();
$validator = Validator::make($input, [
        'name' => ['required', 'regex:/^\p{Lu}\p{L}+ \p{Lu}\p{L}+$/u']
    ],
[
    'name.regex' => 'My custom message here'
]);

但我不想每次都输入整个消息,因为它可能稍后会包含其他占位符(可能是全局的),我想使用通过{提供的多语言基本消息{1}}个文件,所以我真的只需要替换validator.php

2 个答案:

答案 0 :(得分:2)

您可以创建自定义规则:

php artisan make:rule CustomRegex

然后更新构造函数以支持格式的正则表达式和描述。

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class CustomRegex implements Rule
{
    /** @var string $attribute The attribute of we are validating. */
    public $attribute;

    /** @var string $description The description of the regex format. */
    public $description;

    /** @var string $regex The regex to validate. */
    public $regex;

    /**
     * Create a new rule instance.
     *
     * @param string $regex The regex to validate.
     * @param string $description The description of the regex format.
     * @return void
     */
    public function __construct(string $regex, string $description)
    {
        $this->regex = $regex;
        $this->description = $description;
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        $this->attribute = $attribute;

        return preg_match($this->regex, $value);
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return trans('validation.custom.name', [
            'attribute' => $this->attribute,
            'format' => $this->description
        ]);
    }
}

然后当你确认:

use App\Rules\CustomRegex;

request()->validate([
    'name' => [
        'required', new CustomRegex('/^\p{Lu}\p{L}+ \p{Lu}\p{L}+$/u', 'The description of your format')
    ]
]);

然后输出消息如下所示:

  

名称必须与给定格式相对应:格式说明!

答案 1 :(得分:0)

我在Laravel 5.6中可以想到的最简单的方法是使用闭包:

// read more http://php.net/manual/en/function.mb-strwidth.php
function mbStrWidth(input) {
        let len = 0;
        for (let i = 0; i < input.length; i++) {
            let code = input.charCodeAt(i);
            if ((code >= 0x0020 && code <= 0x1FFF) || (code >= 0xFF61 && code <= 0xFF9F)) {
                len += 1;
            } else if ((code >= 0x2000 && code <= 0xFF60) || (code >= 0xFFA0)) {
                len += 2;
            } else {
                len += 0;
            }
        }
        return len;
}

在这个闭包中你可以添加你想要的任何东西。您可以计算可读格式表单并将其添加到错误消息中。