Example of Custom validation rules in realodix/urlhub

File app/Rules/StrAlphaUnderscore.php (link to Github)
use Illuminate\Contracts\Validation\Rule;

class StrAlphaUnderscore implements Rule
{
    public function passes($attribute, $value)
    {
        return preg_match('/^[\pL\pM\pN_]+$/u', $value) > 0;
    }

    public function message()
    {
        return 'The :attribute may only contain letters, numbers and underscores.';
    }
}
File app/Http/Requests/StoreUrl.php (link to Github)
use App\Rules\StrAlphaUnderscore;

class StoreUrl extends FormRequest
{
    public function rules()
    {
        return [
            'custom_key' => ['nullable', 'max:20', new StrAlphaUnderscore, 'unique:urls,keyword'],
        ];
    }
}
File app/Http/Controllers/UrlController.php (link to Github)
use App\Rules\StrAlphaUnderscore;
use App\Rules\StrLowercase;
use App\Rules\URL\KeywordBlacklist;

class UrlController extends Controller
{
    public function customKeyValidation(Request $request)
    {
        $v = Validator::make($request->all(), [
            'keyword' => [
                'nullable',
                'max:20',
                'unique:urls',
                new StrAlphaUnderscore,
                new StrLowercase,
                new KeywordBlacklist,
            ],
        ]);

        if ($v->fails()) {
            return response()->json(['errors' => $v->errors()->all()]);
        }

        return response()->json(['success' => 'Available']);
    }
}

Additional resources on custom validation rules: