How do I use .htaccess RewriteRule to change underscores to dashes - apache

I'm working on a site, and its CMS used to save new page urls using the underscore character as a word seperator.
Despite the fact that Google now treats underscore as a word seperator, the SEO powers that be are demanding the site use dashes instead.
This is very easy to do within the CMS, and I can of course change all existing URLs saved in the MySQL database that serves the CMS.
My problem lies in writing a .htaccess rule that will 301 old style underscore seperated links to the new style hyphenated verstion.
I had success using the answers to this Stack Overflow question on other sites, using:
RewriteRule ^([^_]*)_([^_]*_.*) $1-$2 [N]
RewriteRule ^([^_]*)_([^_]*)$ /$1-$2 [L,R=301]
However this CMS site uses a lot of existing rules to produce clean URLs, and I can't get this working in conjunction with the existing rule set.
.htaccess currently looks like this:
Options FollowSymLinks
# RewriteOptions MaxRedirects=50
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^www\.mydomain\.co\.uk$ [NC]
RewriteRule (.*) http://www.mydomain.co.uk/$1 [R=301,L]
#trailing slash enforcement
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !#
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://www.mydomain.co.uk/$1/ [L,R=301]
RewriteRule ^test/([0-9]+)(/)?$ test_htaccess.php?year=$1 [nc]
RewriteRule ^index(/)?$ index.php
RewriteRule ^department/([^/]*)/([^/]*)/([^/]*)(/)?$ ecom/index.php?action=ecom.details&mode=$1&$2=$3 [nc]
RewriteRule ^department/([^/]*)(/)?$ ecom/index.php?action=ecom.details&mode=$1 [nc]
RewriteRule ^product/([^/]*)/([^/]*)/([^/]*)(/)?$ ecom/index.php?action=ecom.pdetails&mode=$1&$2=$3 [nc]
RewriteRule ^product/([^/]*)(/)?$ ecom/index.php?action=ecom.pdetails&mode=$1 [nc]
RewriteRule ^content/([^/]*)(/)?$ ecom/index.php?action=ecom.cdetails&mode=$1 [nc]
RewriteRule ([^/]*)/action/([^/]*)/([^/]*)/([^/]*)/([^/]*)(/)?$ $1/index.php?action=$2&mode=$3&$4=$5 [nc]
RewriteRule ([^/]*)/action/([^/]*)/([^/]*)(/)?$ $1/index.php?action=$2&mode=$3 [nc]
RewriteRule ([^/]*)/action/([^/]*)(/)?$ $1/index.php?action=$2 [nc]
RewriteRule ^eaction/([^/]*)/([^/]*)/([^/]*)/([^/]*)(/)?$ ecom/index.php?action=$1&mode=$2&$3=$4 [nc]
RewriteRule ^eaction/([^/]*)/([^/]*)(/)?$ ecom/index.php?action=$1&mode=$2 [nc]
RewriteRule ^action/([^/]*)/([^/]*)(/)?$ index.php?action=$1&mode=$2 [nc]
RewriteRule ^sid/([^/]*)(/)?$ index.php?sid=$1 [nc]
## Error Handling ##
#RewriteRule ^error/([^/]*)(/)?$ index.php?action=error&mode=$1 [nc]
# ----------------------------------- Content Section ------------------------------ #
#RewriteRule ^([^/]*)(/)?$ index.php?action=cms&mode=$1 [nc]
RewriteRule ^accessibility(/)?$ index.php?action=cms&mode=accessibility
RewriteRule ^terms(/)?$ index.php?action=cms&mode=conditions
RewriteRule ^privacy(/)?$ index.php?action=cms&mode=privacy
RewriteRule ^memberpoints(/)?$ index.php?action=cms&mode=member_points
RewriteRule ^contactus(/)?$ index.php?action=contactus
RewriteRule ^sitemap(/)?$ index.php?action=sitemap
ErrorDocument 404 /index.php?action=error&mode=content
ExpiresDefault "access plus 3 days"
All page URLS are in one of the 3 following formats:
http://www.mydomain.com/department/some_page_address/
http://www.mydomain.com/product/some_page_address/
http://www.mydomain.com/content/some_page_address/
I'm sure I am missing something obvious, but at this level my regex and mod_rewrite skills clearly aren't up to par.
Any ideas would be greatly appreciated!

Just take the rule you were using already:
RewriteRule ^([^_]*)_([^_]*_.*) $1-$2 [N]
RewriteRule ^([^_]*)_([^_]*)$ /$1-$2 [L,R=301]
…and put it before all other rewrite rules, and everything should work.
Also, you used RewriteBase / twice. You can omit it the second time, since it’s already defined.

Related

Index Coverage - Redirect Error from Index.php

I thought I solved this problem two years ago but now since a couple of weeks I get harassed by the Google Search Console with "Index Coverage" referring to the /index.php of my homepage (all variants of my website are listed in the Search Console and I have a canonical URL in the head part). Also, if I call my www.xxx./index.php it says "Page doesn't work - too many redirects".
Now I know this is not directly a programming issue, but since it involses the htaccess, which is somehow red and black art and just voodoo, I can't get my code to be working correctly/my site being accessible and correctly redirected.
My .htaccess adresses the problem the following. I already tried switching out and deleting parts but it keeps sticking around like a reckless goblin:
// This should redirect to http with www
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^$
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
// This should redirect index.php requests - to be redirected to https://www.
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\/index\.php\ HTTP/
RewriteRule ^index\.php$ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
// Redirect from capital Index.php to index.php
RewriteRule ^Index\.php$ /index.php [R=301,L]
// This redirects from /html and /index requests combined with .php to the https:// version
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.(html?|php)\ HTTP/
RewriteRule ^index\.(html?|php)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteRule ^index\$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
// I'm not sure anymore...
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*[^/])$ /$1/ [L,R]
Edit: I feel that the problem is - like my browser and the search console says - that too many redirects happen (to www.xxx.de/index.php). So I tried out different .htaccess parts and deleting some to minimize the redirections, which for now doesn't seem to work.
I assembled the parts together on my own (not via a framework), I guess that explains sth.
Edit 2: After I deleted line after line and tested the effects, the only part that affects the /index.php is as expected the RewriteRule ^index\.(html?|php)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L], but then the website is also simply accessible under /index.php
What about replacing
RewriteRule ^index\.php$ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
with
RewriteRule ^index\.php$ https://www.%{HTTP_HOST}/ [R=301,L]
Since essentially what you want is to redirect the users that referenced /index.php to /?
I replaced
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\/index\.php\ HTTP/
RewriteRule ^index\.php$ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteRule ^Index\.php$ /index.php [R=301,L]
with
RewriteCond %{QUERY_STRING} ^$
RewriteCond %{THE_REQUEST} /index\.php
RewriteRule ^index\.php https://www.%{HTTP_HOST}/ [R=301,L]
RewriteRule ^Index\.php$ /index.php [R=301,L]
and now /index.php is correctly redirected to my www.xxx.net/ without any loop.

Simplifying a series of redirections using mod_rewrite

My client has an SSL cert for MAINSITE.com but gets a lot of traffic via OTHERSITE.com.
Client would like all visitors to use HTTPS all the time.
So my rules start out by checking for OTHERSITE.com and redirecting to https://MAINSITE.com if found.
Then I check to see if we are using HTTPS and redirect if not.
Then there are a series of rules aimed at using the sub-directories in the URL to pull content and load templates.
My question is whether these rules are as efficient as the should be and if anyone sees issues with how they are written? I'm no mod_rewrite expert.
Plus we have had a few users who reported IE bailing out on them when the WWW version of the URL was loaded but I can't see why? Any advice?
ErrorDocument 404 /index.php
RewriteEngine on
RewriteCond %{HTTP_HOST} OTHERSITE.com [NC]
RewriteRule ^(.*)$ https://MAINSITE.com/$1 [L,R=301]
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteBase /
RewriteRule ^products - [L,NC]
RewriteRule ^sauces$ /sauces.php?sauce=our-hot-sauce [L,QSA]
RewriteRule ^sauces/([^/\.]+)/?$ /sauces.php?sauce=$1 [L,QSA]
RewriteRule ^recipes/([^/\.]+)/?$ /recipes.php?cat=$1 [L,QSA]
# user has cleared recipe name but not cat AND left trailing slash
RewriteRule ^recipe/([^/\.]+)/$ /recipes.php?cat=$1 [L,QSA]
# has sauce/cat and recipe name
RewriteRule ^recipe/([^/\.]+)/([^/\.]+)/?$ /recipe.php?cat=$1&rec=$2 [L,QSA]
# user has cleared recipe name but not cat
RewriteRule ^recipe/([^/\.]+)$ /recipes.php?cat=$1 [L,QSA]
RewriteRule ^([^/\.]+)/?$ /page.php?page=$1 [L,QSA]
RewriteRule ^([^/\.]+)/([^/\.]+)/?$ /page.php?page=$1&sub=$2 [L,QSA]
RewriteRule ^([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ /page.php?page=$1&sub=$2&subsub=$3 [L,QSA]
RewriteRule ^([^/\.]+)/([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ /page.php?page=$1&sub=$2&subsub=$3&subsubsub=$4 [L,QSA]
RewriteRule ^([^/\.]+)/([^/\.]+)/([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ /page.php?page=$1&sub=$2&subsub=$3&subsubsub=$4&subsubsubsub=$5 [L,QSA]
Rest of the rules like fine but first 2 301 rules can be combined into one:
RewriteCond %{HTTP_HOST} ^(www\.)?OTHERSITE\.com$ [NC,OR]
RewriteCond %{HTTPS} off
RewriteRule ^ https://MAINSITE.com%{REQUEST_URI} [L,R=301,NE]

Extra lines in .htaccess file

I want to clean-up my .htaccess file of any unnecessary lines of code. This is what I have on there right now:
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{HTTP_HOST} !^www.aicmillworks.com$ [NC]
RewriteRule ^(.*)$ http://www.aicmillworks.com/$1 [L,R=301]
ReWriteRule ^home$ / [R=301,L]
RewriteCond %{THE_REQUEST} \ /([^\?\ .]*)\.(?:\?|\ |$)
RewriteRule ^ /%1 [L,R=301]
RewriteCond %{HTTP_USER_AGENT} libwww-perl.*
RewriteRule .* – [F,L]
The two lines after "RewriteEngine on" are for redirecting pages with non-www to www. All lines after that, I am not sure what they do or why they are there. Would it be better to remove them or are they important to my website somehow? What do they do?
I'm not entirely sure what the third one does, but the rest of the rules are explained below.
# Redirect: prepend www. if the domain does not start with www.
RewriteCond %{HTTP_HOST} !^www.aicmillworks.com$ [NC]
RewriteRule ^(.*)$ http://www.aicmillworks.com/$1 [L,R=301]
# Redirect: /home to /
ReWriteRule ^home$ / [R=301,L]
# Redirect: strip the file format. So /test.html redirects to /test
# I tried testing this on your site, but it didn't work, so I'm not sure if you have this rule enabled or not.
RewriteCond %{THE_REQUEST} \ /([^\?\ .]*)\.(?:\?|\ |$)
RewriteRule ^ /%1 [L,R=301]
# Block libwww-perl from your website. Usually for blocking bots
RewriteCond %{HTTP_USER_AGENT} libwww-perl.*
RewriteRule .* – [F,L]
As for "Would it be better to remove them or are they important to my website somehow?", they certainly won't hurt your website, so you may as well leave them.

Mod Rewrite with multiple parameters

I'm trying to setup a rewrite rule so that any text in place of a subdomain will be parameter one and any text after the first forward slash will be parameter two but I'm struggling with regex and am unsure about rewrite terminology.
For example, if someone requested:
joebloggs.mydomain.com
I would like them to see:
mydomain.com/index.php?site=joebloggs
Also, if someone requested:
joebloggs.mydomain.com/contact
I would like them to see:
mydomain.com/index.php?site=joebloggs&page=contact
By "see" I mean see the page, rather than see the URL - it's a CMS-like project so you can probably see where I'm going with it. Also, I've worked out how to remove www. so that's not an issue :)
EDIT
Current .htaccess is:
RewriteEngine On
# Remove trailing slash
RewriteRule ^(.+)/$ $1 [L]
# Remove www
RewriteCond %{HTTP_HOST} ^www.richardmjenkins.com$ [NC]
RewriteRule ^(.*)$ http://richardmjenkins.com/$1 [R=301,L]
# Rewrite for site/page pair
RewriteCond %{HTTP_HOST} ^(.*)\.richardmjenkins\.com$ [NC]
RewriteCond %{REQUEST_URI} !p.php
RewriteRule ^(.+/)?([^/]*)$ p.php?s=%1&p=$2 [QSA,L,NC]
RewriteCond %{HTTP_HOST} ^(.*)\.richardmjenkins\.com$ [NC]
RewriteCond %{REQUEST_URI} !p.php
RewriteRule ^$ p.php?s=%1 [QSA,L,NC]
1. In your host panel : add a subdomain with name : * for enable all subdomains
2. this is your htaccess code :
RewriteEngine On
Options +Followsymlinks
RewriteCond %{HTTP_HOST} ^(.*)\.mydomain\.com$ [NC]
RewriteRule ^$ index.php?site=%1 [QSA,L,NC]
RewriteCond %{HTTP_HOST} ^(.*)\.mydomain\.com$ [NC]
RewriteRule ^([^/]+)/?$ index.php?site=%1&page=$1 [QSA,L,NC]
Enable mod_rewrite and .htaccess through httpd.conf and then put this code in your .htaccess under DOCUMENT_ROOT directory:
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^((?!www)[^.]+)\.(mydomain\.com)$ [NC]
RewriteRule ^$ index.php?site=%1 [L,QSA]
RewriteCond %{HTTP_HOST} ^((?!www)[^.]+)\.(mydomain\.com)$ [NC]
RewriteRule ^(.+)$ index.php?site=%1&page=%2 [L,QSA]

mod redirect and rewrites ( Part 2 )

Further to my previous questions i am getting my self into a mess, so i will try and lay my problem/s out as best as i can here.
I am tidying up my URL structure but have the problem that my urls are well indexed in Search engines, so i need to rewrite my urls while also redirect them.
With help earlier on a previous question i currently have the following in my .htaccess
Options +FollowSymlinks
RewriteEngine on
rewritecond %{http_host} ^mydomain.com [nc]
rewriterule ^(.*)$ http://www.mydomain.com/$1 [r=301,nc]
# Rewrite all index.php to root: / ( with perm redirect )
RewriteCond %{THE_REQUEST} ^.*/index.php
RewriteRule ^(.*)index.php$ http://www.mydomain.com/$1 [R=301]
# Rewrite A newly added section rewrite ( no redirect required )
RewriteRule ^products/digital_imaging/([^/]*)/([^/]*)$ /products/digital_xray.php?id=$1&product=$2 [L]
# Rewrite dental news article to neat nice url
RewriteRule ^dental_news/([^/]*)/([^/]*)$ news/dentistry_dental/article_detail.php?article=$1&title=$2&redirect [L]
#Conditional rewrite of old news article path to new one with 301 redirect
RewriteCond %{REQUEST_URI} !^/dental_news/
RewriteCond %{QUERY_STRING} article=([0-9]*)&title=([^&]*)$
RewriteRule (.*) /dental_news/%1/%2? [L,R=301]
So, this is all working as expected, but i have another url that ends in a index.php that sometimes but not always has php variables, this i also need to rewrite and redirect, by trying to do it myself i am creating a conflict of some sorts, and its not working as expected.
The URL i need to rewrite & redirect with a 301 is below
http://www.mydomain.com/news/dentistry_dental/index.php?month=February&year=2011
With the previous index.php rule it currently displays as
http://www.mydomain.com/news/dentistry_dental/?month=February&year=2011
Half way there i guess... I need it to be the following
http://www.mydomain.com/dental_news/February/2011
Baring in mind that the url sometimes has no variables as below
http://www.mydomain.com/news/dentistry_dental/index.php
Which is currently with the index.php rule above is showing as
http://www.mydomain.com/news/dentistry_dental/
This needs to be
http://www.mydomain.com/dental_news/
So yes, i am totally crap at this stuff, it is entirely new to me, so if i can get this sorted ill be a very happy bunny indeed!
Thanks All
EDIT
Ok my current .htaccess looks as below.
Options +FollowSymlinks
RewriteEngine on
rewritecond %{http_host} ^mydomain.com [nc]
rewriterule ^(.*)$ http://www.mydomain.com/$1 [r=301,nc]
# Rewrite all index.php to root: / ( with perm redirect )
RewriteCond %{THE_REQUEST} ^.*/index.php
RewriteRule ^(.*)index.php$ http://www.mydomain.com/$1 [R=301]
RewriteRule ^products/digital_imaging/([^/]*)/([^/]*)$ /products/digital_xray.php?id=$1&product=$2 [L]
# Rewrite dental news article to neat nice url
RewriteRule ^dental_news/([^/]*)/([^/]*)$ news/dentistry_dental/article_detail.php?article=$1&title=$2&redirect [L]
#Conditional rewrite of old news article path to new one with 301 redirect
RewriteCond %{REQUEST_URI} !^/dental_news/
RewriteCond %{QUERY_STRING} article=([0-9]*)&title=([^&]*)$
RewriteRule (.*) /dental_news/%1/%2? [L,R=301]
RewriteCond %{QUERY_STRING} month=([^&]*)&year=([^&]*)
RewriteRule (.*) /dental_news/%1/%2? [R=301]
RewriteRule news/dentistry_dental/$ /dental_news/ [R=301]
RewriteRule ^dental_news/$ /news/dentistry_dental/index.php [L]
As it stands with this, The following occurs
www.mydomain.com/news/dentistry_dental/index.php
-> www.mydomain.com/dental_news/
( ^ Correct )
www.mydomain.com/news/dentistry_dental/index.php?month=May&year=2011
-> www.mydomain.com/dental_news/April/2011
( ^ Wrong : Showing right path in url bar, but displaying article_detail.php instead of index.php with variables)
I am guessing that 2 of the rules are similar and one is picking up the index.php with year and month variables and sending to article_detail page. I might be wrong however and i have no idea how to fix.
EDIT #2
Current .htaccess as below.
Options +FollowSymlinks
RewriteEngine on
rewritecond %{http_host} ^dentalsupportuk.com [nc]
rewriterule ^(.*)$ http://www.dentalsupportuk.com/$1 [r=301,nc]
# Rewrite all index.php to root: / ( with perm redirect )
RewriteCond %{THE_REQUEST} ^.*/index.php
RewriteRule ^(.*)index.php$ http://www.dentalsupportuk.com/$1 [R=301]
RewriteRule ^products/digital_imaging/([^/]*)/([^/]*)$ /products/digital_xray.php?id=$1&product=$2 [L]
# Rewrite dental news article to neat nice url
RewriteRule ^dental_news/([0-9]*)/([^/]*)$ news/dentistry_dental/article_detail.php?article=$1&title=$2&redirect [L]
#Conditional rewrite of old news article path to new one with 301 redirect
RewriteCond %{REQUEST_URI} !^/dental_news/
RewriteCond %{QUERY_STRING} article=([0-9]*)&title=([^&]*)$
RewriteRule (.*) /dental_news/%1/%2? [L,R=301]
RewriteCond %{QUERY_STRING} month=([^&]*)&year=([^&]*)
RewriteRule (.*) /dental_news/%1/%2? [R=301]
RewriteRule news/dentistry_dental/$ /dental_news/ [R=301]
RewriteRule ^dental_news/([a-zA-Z]*)/([0-9]*)$ news/dentistry_dental/index.php?month=$1&year=$2&redirect [L]
www.mydomain.com/dental_news/ is now rewriting to www.mydomain.com/dental_news/ which doesnt exist so 404 error ( should be rewriting to www.mydomain.com/news/dentistry_dental/ )
www.mydomain.com/dental_news/100/some-title is now rewriting as expected to www.mydomain.com/news/dentistry_dental/article_detail.php with the variables ( working )
www.mydomain.com/news/dentistry_dental/article_detail.php?article=100&title=some-title is redirecting as expected to www.mydomain.com/dental_news/100/some-title and displaying correctly ( working )
www.mydomain.com/news/dentistry_dental/index.php?month=May&year=2010 is redirecting but crashing out Firefox stating ( Firefox has detected that the server is redirecting the request for this address in a way that will never complete. ) ( Not Working, is this some sort of loop causing this? )
www.mydomain.com/dental_news/July/2010/ the rewriting is giving me a 404 error.
So yes, im all over the place, maybe ive put in wrong order or something, but the more i mess the more im scared of breaking everything. Any ideas?
Regards
M
Try adding the follow two rules:
RewriteCond %{QUERY_STRING} month=([^&]*)&year=([^&]*)
RewriteRule (.*) /dental_news/%1/%2? [R=301]
RewriteRule news/dentistry_dental/$ /dental_news/ [R=301]
I don't believe it causes any conflicts, and seems to cover the two scenarios you described.
EDIT
OK, so if I'm getting this correct, the URLs that are /dental_news/2968/Redefining-oral-hygiene-intervention should be rewritten to /news/dentistry_dental/article_detail.php with the proper querystrings. And then the /dental_news/April/2011 should be rewritten to /news/dentistry_dental/index.php. So...if that is the case, you should be able to add the following rule:
RewriteRule ^dental_news/([a-zA-Z]*)/([0-9]*)$ news/dentistry_dental/index.php?month=$1&year=$2&redirect [L]
It would also probably make sense to make the following update:
Current: RewriteRule ^dental_news/([^/]*)/([^/]*)$ news/dentistry_dental/article_detail.php?article=$1&title=$2&redirect [L]
Updated: RewriteRule ^dental_news/([0-9]*)/([^/]*)$ news/dentistry_dental/article_detail.php?article=$1&title=$2&redirect [L]
The difference there being that it is more specific, and the first regex group will only match a group of digits, and will help to avoid conflict with your rule that is rewriting to the index.php file.
EDIT 2
I believe I tested all of the URLs you provided, and they seem to be working now. There were a couple of redirect loops that we weren't accounting for. Hopefully this will help...
Options +FollowSymlinks
RewriteEngine on
rewritecond %{http_host} ^mydomain.com [nc]
rewriterule ^(.*)$ http://www.mydomain.com/$1 [r=301,nc]
# Rewrite all index.php to root: / ( with perm redirect )
RewriteCond %{THE_REQUEST} ^.*/index.php
RewriteRule ^(.*)index.php$ http://www.mydomain.com/$1 [R=301]
RewriteRule ^products/digital_imaging/([^/]*)/([^/]*)$ /products/digital_xray.php?id=$1&product=$2 [L]
RewriteRule dental_news/$ /news/dentistry_dental/?rewrite [L]
# Rewrite dental news article to neat nice url
# Protect from looping because of previous rules
RewriteCond %{QUERY_STRING} !rewrite
RewriteRule ^dental_news/([0-9]*)/([^/]*)$ news/dentistry_dental/article_detail.php?article=$1&title=$2&rewrite [L]
#Conditional rewrite of old news article path to new one with 301 redirect
RewriteCond %{REQUEST_URI} !^/dental_news/
RewriteCond %{QUERY_STRING} article=([0-9]*)&title=([^&]*)$
RewriteRule (.*) /dental_news/%1/%2? [L,R=301]
RewriteCond %{REQUEST_URI} !^/dental_news/
RewriteCond %{QUERY_STRING} month=([^&]*)&year=([^&]*)$
RewriteRule (.*) /dental_news/%1/%2? [R=301]
# Protect from looping because of previous rules
RewriteCond %{QUERY_STRING} !rewrite
RewriteRule news/dentistry_dental/$ /dental_news/ [R=301]
# Protect from looping because of previous rules
RewriteCond %{QUERY_STRING} !rewrite
RewriteRule ^dental_news/([a-zA-Z]*)/([0-9]*)/?$ news/dentistry_dental/index.php?month=$1&year=$2&rewrite [L]
Hope this helps.