Handy RegEx Constraints in Laravel Routes

It’s a well-known feature, but still in some cases it may require longer research to find the good regex patterns for defining constraints for our route parameters. Let’s see some idea.

Getting Started

First of all, let’s see how to even use patterns to create rules for our routes. In your routes file – web.php or api.php – where you define your routes, you can add other options as well, like the patterns you wish to use.

Route::get('user/{user}', '[email protected]')->where('user', '[a-z]+');

Also, we have the ability to pass an array in case we have multiple parameters in or routes:

Route::get('user/{user}/{account}', '[email protected]')->where([
    'user' => '[a-z]+',
    'account' => '[0-9]+',
]);
In some cases, you may define global patterns that affect all your routes.

The documentation covers the routing well, so for more information please visit the official docs. So, let’s move on and see some handy constraints.

Allow Only Certain Keywords

It’s possible we want to match only with some keywords. If anything else is passed to the router, it should not accept it. With regex, we can easily create a set and match it with the given parameter.

Router::get('pages/{page}', ...)->where('page', 'about|contact');

Match Everything Except Some Keywords

In some cases, you may have some preserved keywords. Without regular expressions, we would have to define the routes individually and put them before the dynamic route. With regular expressions, we can tell the router, match everything but the given keywords.

// Without regex
Router::get('pages/about', ...);
Router::get('pages/contact', ...);
Router::get('pages/{page}', ...);

// With regex
Router::get('pages/{page}', ...)->where('page', '^(?!about|contact)$');

We have the ability to handle the exceptions later as we want since the router won’t trigger any controller if the given keywords are present in the {page} parameter.

Handling Everything as One Parameter

Formerly we posted about serving static content via Laravel. If you visit the post, you can see, Laravel provides only the root of the route and after a specific point – for example, blog – the structure represents the static content we need to serve. Let’s say we have a blog/categories/laravel route. We want Laravel to handle the categories/laravel as one parameter, that we can use later.

Route::get('blog/{slug?}', 'BlogController')->where('slug', '(.*)');

Whatever comes after the blog keyword, Laravel handles it as one string, so we can use it in our controller how we want. Also note, the slug parameter is optional since we added the ? to the parameter.

Must be a Specific Pattern

Let’s say we need to use a very specific pattern for our routes. For example, 4 numbers 4 letters 4 numbers, separated with a dash. Like 1234-abcd-5678.

Route::get('transaction/{id}', ...)->where('id', '^([0-9]{4}-[a-z]{4}-[0-9]{4})$');

If we get any ID that not matches the pattern – for example, no dash, 5 digits, mixed digits and letters – it just won’t match.

Summary

We can see, that we have an almost infinite way to make rules that we want to apply to our routes. We can make it global or local, we can assign multiple or single restrictions. The point is, you need a little knowledge of regular expressions and you can create basically any pattern you wish.

Special thanks for the following recource(s): Icon made by Smashicons from www.flaticon.com