Using regular expression in htaccess for 301 redirects

26,925

Using mod_alias:

RedirectMatch 301 ^/news/(.+?)(-[0-9]+)?$ /blog/$1

or using mod_rewrite:

RewriteEngine On
RewriteRule ^news/(.+?)(-[0-9]+)?$ /blog/$1 [L,R=301]
Share:
26,925
Zabs
Author by

Zabs

PHP Developer

Updated on July 05, 2022

Comments

  • Zabs
    Zabs almost 2 years

    I have a Wordpress blog where I am redirecting blog posts from my old blog to my new blog in the format below:

    The old blog is called 'News' and the new blog is simply called 'Blog' - both exist on the same domain in a subdirectory as indicated below.

    OLD 'News' blog structure

    http://www.example.com/news/new-android-os-3431
    

    NEW 'Blog' blog structure

    http://www.example.com/blog/new-android-os
    

    Essentially this redirect needs to do 2 things:-

    1. Redirect to 'blog' directory
    2. Retain the post name in the same structure but remove the last set of numbers at the end of the URL

    I have around 900+ posts that I need to setup redirects for - I know I could manually add each one in but that would take some time. Could anyone indicate if this could be using an regular expression directly within the htaccess file to minimise this process?

    My htaccess currently looks like this:

    # BEGIN WordPress
    <IfModule mod_rewrite.c>
     RewriteEngine On
     RewriteBase /news/
     RewriteRule ^index\.php$ - [L]
     RewriteCond %{REQUEST_FILENAME} !-f
     RewriteCond %{REQUEST_FILENAME} !-d
     RewriteRule . /news/index.php [L]
    </IfModule>
    # END WordPress
    
  • Zabs
    Zabs about 11 years
    Thanks Jon i'll give that a crack - I really need to learn RegExp :)
  • Zabs
    Zabs about 11 years
    This almost works - any idea how I do the following:- Make $1 return just: 'new-android-os' Make $2 return the remainder '-3431' I presume I would need to somehow start the regex from the end of the string and remove the last integer.
  • Zabs
    Zabs about 11 years
    Upon 2nd thoughts having checked the regex again they should both work (its been a long day) For some reason - even though I know the regex is correct (as per the RegExpr app by gskinner) for some reason Wordpress itself redirects it to the 'blog' blog but with the existing post title without removing the last section with the numbers.. weird?!
  • Jon Lin
    Jon Lin about 11 years
    @Zabs That's what it should be doing. Given the URI /news/abcd-efg-hijk-1234, $1 would be abcd-efg-hijk, grouped by the (.+?) expression and $2 would be -1234 grouped by the (optional) (-[0-9]+)? expression.
  • Zabs
    Zabs about 11 years
    I'll have to look more into my WP installation as like Jon said this expression does work perfectly fine when I run this through a application like 'RegExr' which can generate & test expressions. But for some weird reason my Wordpress blog always seems to append the 'post-id' which I am trying to remove. I'll keep trying and let you know how I get on.
  • Zabs
    Zabs about 11 years
    Thanks - i'm going to accept the answer as I know its 100% correct - I think I have something odd with the Wordpress installation which maybe effecting the redirects at the moment - Will do more investigation.
  • Zabs
    Zabs about 11 years
    = i've looked at other htaccess/regex questions on stackoverflow - you are quite the guru with Regular Expressions. I am impressed! :)
  • Zabs
    Zabs about 11 years
    In the end this worked (basically the same as Jon Lins with a minor difference) Thanks again Jon! RedirectMatch ^/news/(.+?)(-[0-9]+)(/)?$ /blog/$1
  • thedudecodes
    thedudecodes almost 8 years
    anyone who know how to write it please help me I want to redirect to the same url ex- mrpmediaworks.com/work/upasna-group-self-branding when user enters like - mrpmediaworks.com/work/upasna-group-self-branding (/ at the end) how to remove '/' only the last one redirect back to the same url I have almost 80 urls which is slug.. I have written the rule from the above answer RedirectMatch 301 ^work/(.+?)(-[0-9]+)?/$ /work/(.+?)(-[0-9]+)?$ please help me