Regex Redirects in WordPress: A Practical Guide
One pattern rule can retire a thousand old URLs, or take your whole site with it. Here is how to write a regex redirect that does only what you meant it to do.
On this page
A regex redirect matches a pattern of URLs instead of one exact path, and it can carry a piece of the old address into the new one. One rule saying “anything under /blog/ goes to the same thing under /articles/” replaces a thousand hand-written rules, and it keeps working for URLs you have forgotten about. That power is the whole appeal, and also the whole danger: a pattern with one character out of place can match every URL on your site.
Here is when a pattern is the right tool, the small amount of syntax that covers most real cases, four recipes you can adapt, and the specific mistakes that turn a migration into an outage.
What a Regex Redirect Actually Does
A normal redirect rule says: this exact path goes to that exact destination. A pattern rule says: any path shaped like this goes to a destination built from what I matched. The building part is what makes it useful. Parentheses capture a section of the old URL, and $1 drops that captured section into the target, so the slug survives the move.
The classic form looks like ^/blog/(.*)$ sending traffic to /articles/$1. A visit to /blog/best-router lands on /articles/best-router without anyone writing that pair down. On Apache the same idea is spelled RedirectMatch 301 regex target, and pattern-capable WordPress plugins use the same building blocks in a form field.
When You Need One, and When You Do Not
Reach for a pattern when the same change applies to many URLs at once: a folder rename, a permalink structure change, dropping a file extension across an old static site, or collapsing a category level you no longer use. These are jobs where you genuinely cannot list every URL, either because there are hundreds or because some of them only exist in somebody’s bookmarks.
Everywhere else, if you can list the URLs, list them. Ten moved posts are ten exact rules, and exact rules are readable a year later by someone who is not you. A pattern is a promise about URLs that do not exist yet, so it should only be made when you actually mean to make it.
The Syntax That Covers Most Cases
Six pieces do nearly all the work.
^ anchors to the start of the path, and $ anchors to the end. Together they mean the pattern must describe the whole path, not just a fragment of it. . means any single character, which is why a literal dot must be escaped as \. when you are matching a file extension. * means “the thing before this, repeated any number of times”, so (.*) is the everyday capture group: match anything, and remember it. $1 is where the first captured group is inserted in the destination. And [0-9]{4} matches exactly four digits, which is how you describe a year in a dated permalink.
Read one out loud and it stops being cryptic. ^/product/(.*)\.html$ says: start of path, then /product/, then remember everything up to a literal .html at the end of the path.
Four Patterns That Cover Most Real Moves
Renaming a folder: match ^/blog/(.*)$ and send it to /articles/$1. Every post keeps its slug under the new parent.
Dropping dates from permalinks: match ^/[0-9]{4}/[0-9]{2}/(.*)$ and send it to /$1, which turns /2019/04/my-post into /my-post. This is the most common WordPress migration of the lot.
Retiring a file extension after moving off a static site: match ^/(.*)\.html$ and send it to /$1/, so /about.html becomes /about/.
Collapsing a level: match ^/shop/category/(.*)$ and send it to /shop/$1. Same products, one less step in the path.
One limitation to remember: these patterns are matched against the path, so a query string like ?ref=newsletter is not part of what they see. Parameters usually survive the redirect on their own, but you cannot match on them with a path pattern.
The Traps That Break Sites
Unanchored patterns are the first one. /blog with no ^ matches /blog, but it also matches /my-blog-post and /category/blogging. Anchor everything.
Self-matching destinations are the second, and the worst. If ^/blog/(.*)$ points at /blog/archive/$1, the destination still starts with /blog/, so it matches the rule again and you have built an infinite loop. The rule to memorise: the destination must not match the pattern. Our guide to fixing a WordPress redirect loop covers what to do once one is already live.
The rest are smaller but common. A greedy .* can swallow more of the URL than you intended. An unescaped dot turns /aboutXhtml into a match. Order matters, because most engines take the first match, so narrow rules belong above broad ones. And the status code still needs a decision: a permanent move wants a 301, as covered in 301 vs 302.
Where you put the rule matters too. A pattern in .htaccess takes effect instantly with no plugin overhead, and a syntax error there takes the entire site down with a 500, which is the trade-off we laid out in htaccess vs plugin redirects.
Test Before You Ship
Write the pattern, then write two lists before touching the site. Five URLs that must match, with the destination you expect for each. Five that must not, and put the destination URL itself at the top of that list, since that single test catches the loop before it exists.
Apply the rule on staging if you have one, walk both lists, then deploy and run a few real URLs through a redirect checker to confirm the status code and that each one resolves in a single hop rather than a chain. A week later, read your 404 log: whatever the pattern missed will be sitting in it.
Where Plain Rules Beat Patterns
Most WordPress sites need one or two pattern rules during a migration and then never again. The everyday work is different: a campaign link, a cloaked affiliate path, a country-specific offer, a printed short link. Those are single destinations that need targeting and tracking, not pattern matching.
That is the job DevDome Redirect Manager is built for. Rules are exact paths rather than regular expressions, with the redirect type set per rule as 301, 302, 307 or 308, geo and device targeting, scheduling, destination rotation, per-rule click stats, and cache purging across 10 WordPress cache plugins so a stale cache never serves an old target. For a bulk pattern migration, use a pattern-capable plugin or a server rule instead; we lined the options up in our redirect plugin comparison.
One last thing about the numbers those rules report. A pattern that covers a folder of outbound links will collect plenty of hits that never came from a person, because crawlers work through predictable folders exhaustively. Before you conclude a redirect is popular, check the split, as affiliate click fraud explains in detail.
Disclosure: DevDome publishes this blog and makes the products it mentions. We describe what they do rather than promise results.
Key takeaways
- A regex redirect matches a pattern of URLs instead of one exact path, and can carry part of the old URL into the new one.
- You need one when the same change applies to many URLs at once, and not before.
- Anchor every pattern with ^ and $, or it will match more than you meant.
- A pattern that also matches its own destination is the fastest way to build a redirect loop.
- Test each pattern against URLs that must match and URLs that must not, before it goes live.
Sources
- Apache: mod_alias, Redirect and RedirectMatch — the RedirectMatch syntax and how parenthesised matches are substituted into the target
- MDN: regular expressions guide — anchors, groups, quantifiers and escaping, with runnable examples
- Google Search Central: redirects and Google Search — how search engines treat permanent versus temporary redirects during a site move
Links last checked August 18, 2026.
Frequently asked questions
Does WordPress support regex redirects out of the box?
No. WordPress handles a few redirects of its own, such as sending an old slug to the new one after you rename a post, but there is no interface for pattern rules. You get them either from a plugin that supports pattern matching or from your server configuration, using RedirectMatch on Apache or a location block with a regular expression on Nginx.
What is the difference between a wildcard and a regex?
A wildcard is a single stand-in for any characters, usually written as an asterisk, and that is all it does. A regular expression is a small language: it can anchor to the start or end of a path, require a digit, make a section optional, and capture part of the match so you can reuse it in the destination. Wildcards are easier to read; regex is what you need when the destination depends on the old URL.
Do regex redirects slow a site down?
A handful of patterns is not measurable. The cost appears when a site accumulates hundreds of unanchored patterns that every single request has to be tested against, including requests for images and assets. Keep exact moves as exact rules, keep patterns few and anchored, and delete migration rules once the old URLs have stopped being requested.
Why does my regex redirect loop?
Almost always because the pattern matches its own destination. If ^/blog/(.*)$ redirects to /blog/archive/$1, the new URL still starts with /blog/, so it matches again, and again. Fix it by making the destination fall outside the pattern, or by adding an exclusion for the destination path, then retest with the destination URL itself as your first test case.