Using a regex to match a substring in a Laravel route

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company

Mastering Route Matching: Using Regex Effectively in Laravel

As developers working with routing systems like Laravel, we often encounter the need to match complex patterns within URL slugs. The desire to use Regular Expressions (regex) to validate or extract parts of a dynamic segment is very common. However, the way regex interacts with Laravel's route definition syntax can be surprisingly tricky.

This post will dive into why your initial attempts might not have worked and provide the correct, robust methods for achieving precise substring matching within your Laravel routes.

The Misconception: Regex vs. Route Parameters

The core confusion often lies in conflating two separate systems:

  1. URL Path Matching (Laravel Routing): This system uses defined placeholders (like {slug}) and pattern matching to determine if a requested URL matches a defined route.
  2. String Pattern Matching (Regex): This is used for complex text searching within strings, files, or database queries.

Your attempt using Route::any('{myslug}/page/', ...)->where('myslug','/bar/'); attempts to force string containment logic into the routing definition. Laravel's primary route matching mechanism handles segment boundaries more strictly than simple substring checks. When you use regex within a route parameter definition, you are telling the router how to interpret that specific segment, not performing arbitrary text searching across the entire slug.

The Correct Approach: Regex for Route Segment Validation

If you need to ensure that a dynamic segment (like {myslug}) strictly adheres to a certain pattern—for example, ensuring it only contains alphanumeric characters and hyphens—then regex is the perfect tool. This allows Laravel's router to validate the URI structure before it even hits your controller logic.

To use regex in route definitions, you place the expression directly inside the curly braces:

// Example: Only allow slugs consisting of letters, numbers, and hyphens.
Route::get('/{myslug:[a-zA-Z0-9\-]+}/page', function ($myslug) {
    // $myslug will only contain valid slug characters.
})->name('bar-page');

In this example, the router automatically enforces that the value provided for myslug must match the pattern [a-zA-Z0-9\-]+. If a user tries to access /foo/bar/page, and bar doesn't conform to the required slug pattern, Laravel will return a 404 error immediately.

Handling Substring Matching in Controller Logic

If your requirement is simply: "Does the full slug contain the word 'bar'?", then performing this kind of semantic check is better handled within your application logic, rather than relying solely on routing syntax. This keeps your routing clean and separates concerns effectively.

Here is how you would handle that specific requirement in your controller, leveraging Eloquent or basic string functions:

// In a Controller method (e.g., MyBarController@index)

public function index(Request $request)
{
    $slug = $request->route('myslug'); // Retrieve the matched slug from the route

    if (str_contains($slug, 'bar')) {
        // The slug contains "bar", proceed with logic specific to bar-related content.
        return view('bar_content');
    }

    // If it doesn't contain "bar", handle the default case.
    return redirect()->route('default')->withErrors('Slug does not contain "bar".');
}

This approach is more flexible. It allows you to use strict regex for structural validation (in the route) and powerful string methods for semantic content validation (in the controller). This separation of concerns aligns perfectly with the architectural principles promoted by frameworks like Laravel.

Conclusion

Don't let regex become a catch-all solution for routing structure. Use regex where you need to enforce strict structural constraints on URL segments, allowing Laravel’s powerful router to handle the validation efficiently. For checking if a string contains a substring within a dynamic slug, delegate that task to your controller or service layer using standard PHP string functions. By respecting these boundaries, you build more maintainable and predictable applications.