Redirect Types & Concepts

What is a regex redirect?

A regex redirect is a redirect rule that uses a regular expression, commonly abbreviated as regex, to define the URL pattern it matches. Instead of matching a single exact URL or using a simple wildcard asterisk to match any sequence of characters, a regex redirect uses a precise pattern language capable of expressing complex, specific matching logic that wildcards cannot achieve.

Regular expressions are a standardised syntax for describing patterns in text. They are used across programming languages, text editors, databases, and server configuration tools to find, match, and manipulate strings. In the context of redirect management, regex gives you fine-grained control over which URLs a redirect rule applies to: matching only URLs that conform to a precise structural pattern rather than everything that starts with a given prefix or contains a given string.

The power of regex redirects comes from their precision. A wildcard redirect can match everything under a path. A regex redirect can match only URLs where a specific segment is a four-digit number, or only URLs ending in .php, or only URLs where a product ID follows a particular format, or URLs containing optional query parameters in a specific structure. That precision is why regex redirects exist, and why they require more care to configure correctly than simpler redirect types.

How a regex redirect works

A regex redirect rule has the same core components as any redirect rule: a source pattern, a destination, and an HTTP status code. The difference is in how the source pattern is defined and evaluated.

When a request arrives at the server, the requested URL is tested against the regex pattern. The regex engine checks whether the URL matches the pattern according to the regular expression rules, not just whether it contains certain characters, but whether those characters appear in the exact positions, quantities, and relationships the pattern specifies. If the URL matches, the redirect fires. If it does not match, the rule is skipped.

A basic regex pattern matching all URLs ending in .php:

^/(.*)\.php$
^/(.*)\.php$
^/(.*)\.php$

This pattern matches any URL path that starts at the beginning of the path (^/), contains any sequence of characters ((.*)), followed by a literal dot and php (\.php), at the end of the string ($). URLs like /page.php, /products/item.php, and /old-blog/post.php all match. URLs like /page.html or /about do not.


The matched portion, the content captured by the parentheses (.*), can be referenced in the destination URL using a back-reference, typically written as $1 or \1 depending on the server configuration syntax. This allows the matched value to be inserted into the destination:

^/(.*)\.php$ → /$1
^/(.*)\.php$ → /$1
^/(.*)\.php$ → /$1

This rule redirects /page.php to /page, /products/item.php to /products/item, and so on, stripping the .php extension from every matched URL in a single rule.

Regex syntax fundamentals for redirect rules

Understanding the core regex syntax elements used in redirect rules helps demystify how patterns are constructed and read.

^: anchors the match to the beginning of the string. ^/about matches only URLs that start with /about, not URLs that contain /about somewhere in the middle.

$: anchors the match to the end of the string. /about$ matches only URLs that end with /about, not URLs that have additional characters after it.

.: matches any single character. /ab.ut matches /about, /abcut, /ab3ut, and any other URL with a single character in that position.

\.: a literal dot. The backslash escapes the dot, preventing it from matching any character. /page\.php matches only /page.php, not /pageXphp.

*: matches zero or more of the preceding element. /page.* matches /page, /pages, /page-title, /page/subpage, and anything else starting with /page.

+: matches one or more of the preceding element. /page.+ matches /pages, /page-title, and anything with at least one character after /page, but not /page itself.

?: matches zero or one of the preceding element. Makes the preceding character or group optional. /colours?/ matches both /colour/ and /colours/.

(): capturing group. Captures the matched content for use in the destination URL as a back-reference. /products/([0-9]+) captures the numeric product ID in the URL.

[]: character class. Matches any single character within the brackets. [0-9] matches any digit. [a-z] matches any lowercase letter. [a-zA-Z0-9] matches any alphanumeric character.

{n}: exact quantifier. [0-9]{4} matches exactly four digits. [0-9]{2,4} matches between two and four digits.

|: alternation. Matches either the pattern on the left or the pattern on the right. /old-name|former-name matches either /old-name or /former-name.

Regex redirects vs wildcard redirects

Wildcard redirects and regex redirects both match patterns of URLs rather than individual exact paths, but they operate at different levels of precision and complexity.

A wildcard redirect uses a simple * character to mean “match anything here.” It is easy to read, easy to configure, and covers the majority of real-world pattern matching needs. A rule like /old-section/* matches every URL under /old-section/ with a single readable rule that anyone can understand at a glance.

A regex redirect uses full regular expression syntax. It can express everything a wildcard can express, /old-section/(.*) is the regex equivalent of /old-section/*, plus an enormous range of patterns that wildcards cannot. The trade-off is complexity. Regex patterns are harder to read, harder to write correctly, and much easier to get subtly wrong in ways that are not immediately obvious.

The practical guidance is to use wildcards by default and reach for regex only when the required matching logic cannot be expressed with a simple wildcard pattern. Most redirect scenarios, domain migrations, section redirects, global fallbacks, can be handled with wildcards. Regex is the right tool for the minority of cases where precision beyond what wildcards offer is genuinely needed.

Common use cases for regex redirects

Removing file extensions: migrating from a technology that exposed file extensions in URLs, .php, .asp, .html, .aspx, to clean URLs. A single regex rule matches all URLs ending in the old extension and redirects them to their clean equivalents:

^/(.*)\.php$ → /$1
^/(.*)\.php$ → /$1
^/(.*)\.php$ → /$1

This handles the entire migration in one rule regardless of how many pages the site has.

Matching numeric IDs: URLs containing product IDs, article IDs, or other numeric segments can be matched precisely with digit patterns. A rule matching /products/([0-9]+) captures only URLs where the segment after /products/ is purely numeric, avoiding false matches on non-numeric paths.

Handling optional URL segments: when a URL structure changes and segments become optional or move position, regex can match both old and new formats in a single rule. A pattern like /blog/(category/)?([a-z0-9-]+) matches URLs both with and without a category segment.

Date-based URL restructuring: blog and news sites commonly include dates in URLs. Moving from /2023/04/post-title to /blog/post-title requires matching the date segments and discarding them. A regex pattern like ^/[0-9]{4}/[0-9]{2}/(.*)$ matches date-prefixed URLs and captures the post slug for use in the destination.

Multiple extension variants: when multiple old file extensions need to be redirected, alternation in regex handles them all in one rule: ^/(.*)\.(php|asp|html|aspx)$ matches URLs ending in any of the listed extensions.

Enforcing URL case: redirecting uppercase or mixed-case URLs to lowercase equivalents requires regex to match the uppercase characters and redirect to normalised versions. This prevents duplicate content from case-insensitive URL handling.

Query string parameter mapping: redirecting URLs with old query parameter structures to new ones. A regex rule can match specific parameter names and values and construct new destination URLs from the captured values.

Subdomain pattern matching: matching subdomains that follow a specific pattern, [a-z]+.example.com for any single-word subdomain, or [0-9]{4}.example.com for year-based subdomains, and routing them to appropriate destinations.

Regex redirects in server configuration

Regex redirects are implemented differently depending on the server environment.

Apache .htaccess: Apache’s mod_rewrite module provides full regex support for redirect rules. The RewriteRule directive accepts regex patterns in the source and supports back-references in the destination:

RewriteEngine On
RewriteRule ^/(.*)\.php$ /$1 [R=301,L]
RewriteEngine On
RewriteRule ^/(.*)\.php$ /$1 [R=301,L]
RewriteEngine On
RewriteRule ^/(.*)\.php$ /$1 [R=301,L]

The R=301 flag specifies a permanent redirect and L marks it as the last rule to be evaluated if it matches.


Nginx: Nginx supports regex in location blocks and rewrite directives. Regex locations are prefixed with ~ for case-sensitive matching or ~* for case-insensitive:

location ~ ^/(.*)\.php$ {
  return 301 

location ~ ^/(.*)\.php$ {
  return 301 

location ~ ^/(.*)\.php$ {
  return 301 

Cloudflare Workers and edge platforms: serverless edge platforms allow custom redirect logic in JavaScript or other languages, where full regex support is available through the standard language RegExp object. This enables the most flexible redirect logic possible, including complex conditional patterns that even server-side regex configuration cannot express.

Redirect management tools: many redirect management platforms support regex patterns in redirect rules, exposing regex syntax in a managed interface without requiring direct server configuration access.

Regex redirects and SEO

Regex redirects have the same SEO implications as any other server-side redirect: the SEO effect is determined by the HTTP status code used, not by the pattern matching method. A regex redirect using a 301 transfers SEO equity and link juice to the destination exactly as a simple path redirect does. A regex redirect using a 302 is treated as temporary.

The SEO-specific concerns with regex redirects relate to correctness rather than the regex mechanism itself.

Over-broad patterns: a regex pattern that matches too many URLs can accidentally redirect pages that should remain live. A pattern intended to match only old .php URLs that inadvertently matches other URLs due to a subtle regex error creates unintended redirects and broken pages. Always test regex patterns against a representative sample of URLs, including URLs that should not match, before deploying.

Redirect chains: a regex rule whose destination URL is itself matched by another redirect rule creates a redirect chain. The captured group from the regex may produce a destination URL that triggers a further redirect. Test the full chain for regex-generated destinations.

Crawl budget: a regex rule matching a large number of URLs on a high-traffic site generates significant redirect activity. Each matched URL consumes crawl budget as Googlebot follows the redirect. Ensuring regex redirects resolve in a single hop to a 200 OK keeps this efficient.

Common mistakes with regex redirects

Unescaped special characters: dots, slashes, and other special characters in URL paths need to be escaped in regex patterns. An unescaped dot matches any character rather than a literal dot: /page.php would match /pageXphp and /page php in addition to /page.php. Always escape literal dots as \. and other special characters appropriately.

Missing anchors: a pattern without ^ and $ anchors matches the pattern anywhere in the URL rather than requiring it at specific positions. /old without anchors matches /old, /older, /bold/old, and any other URL containing the string /old. Adding anchors, ^/old$, restricts the match to the exact intended URL.

Greedy vs lazy matching: the .* pattern is greedy by default: it matches as many characters as possible. In some URL patterns this can cause unexpected behaviour when multiple possible match positions exist. The lazy equivalent .*? matches as few characters as possible. Understanding which behaviour is intended for a given pattern prevents subtle matching errors.

Testing only happy-path URLs: testing a regex pattern only against URLs it is expected to match is insufficient. Always test against URLs that should not match to confirm the pattern does not over-match. A pattern that looks correct when tested against intended URLs may still match unintended ones.

Regex complexity without benefit: using regex for patterns that a simple wildcard could express. ^/blog/(.*)$ does the same job as /blog/* with unnecessary complexity. Reserve regex for cases where wildcards genuinely cannot express the required logic.

Not testing back-references: when a regex rule uses captured groups to construct the destination URL, testing the back-reference output is essential. A capturing group that matches more or less than intended produces incorrect destination URLs. Verify that the captured value inserted into the destination produces the expected result for a range of input URLs.

Related terms

Related terms

Ready to keep every link alive?

Ready to keep every link alive?

Ready to keep every link alive?