Removing additional trailing backslash with .htacess – domain.com/page// - regex

I have content that can display with a double-slash:
domain.com/folder/name//
Obviously this is not ideal.
I want to create a .htaccess 301 rewrite that removes the additional trailing slash:
domain.com/folder/name/
I came-up with:
RewriteRule /(.*)/(.*)// /$1/$2/ [R=301,L]
Though no-dice.

You can't match // in RewriteRule since Apache strips it to single there.
Use RewriteCond instead:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/+(.*?)/+(/.*)$
RewriteRule ^ /%1%2 [R=302,L,NE]

Related

htaccess RewriteRule regex

I have hundreds of these old links I need to redirect.
Here is one example:
/index.php?option=com_content&view=article&id=433:seventh-character-code-categories-and-icd-10-cm&Itemid=101&showall=1
to
/seventh-character-code-categories-and-icd-10-cm
Essentially I need to remove the /index.php?option=com_content&view=article&id=433: part.
I tried this but I am getting confused with the [0-9] and : parts, so the following does not work:
RewriteRule ^/index.php?option=com_content&view=article&id=[0-9]:(.*)$ /$1 [L,R=301]
Say you want to capture from after : to right before & in the query string you mentioned, then try this expression:
^[^\:]*\:([^\&]*)\&.*$
As #starkeen mentioned in comments, you got to check against the query string. This can be done using RewriteCond %{QUERY_STRING}
So if index.php is in the root folder:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^\/index\.php$
RewriteCond %{QUERY_STRING} ^[^\:]*\:([^\&]*)\&.*$
RewriteRule ^(.*)$ http://example.com/%1 [R=301,L]
Here's another example. This one is for a sub folder:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^\/pages\/index\.php$
RewriteCond %{QUERY_STRING} ^[^\:]*\:([^\&]*)\&.*$
RewriteRule ^(.*)$ /pages/%1? [R=301,L]
Also, notice the ? at the end of the url /pages/%1?, this prevents from re-attaching the query string.
Another thing, captured groups will be set to variables %{number} since set in the RewriteCond.
BTW, depending on your server's configuration, you may need to add the NE flag, like [NE,L,R=301] Plus test whether it is necessary to double escape the literal characters.
what is about direct approach. Skip all till semicolon, mach string till & and replace all with first much
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{QUERY_STRING} [^:]+:([\w-]+[^&]).*
RewriteRule .*$ \/%1? [R=301,L]
</IfModule>

Remove multiple trailing slashes in root using htaccess

I have a rule in my htaccess file to remove any extra trailing slashes from a url, this works on sub-directories with any more than 1 trailing slash. However it doesn't work on the root; which i need it to do.
For example.
http://www.example.com/test//// Redirects to http://www.example.com/test/
http://www.example.com/// Needs to redirect to http://www.example.com
Any ideas on what i need to add?. Cheers.
RewriteCond %{REQUEST_URI} ^(.*?)(?:/){2,}$
RewriteRule . %1/ [R=301,L]
For removing multiple slashes anywhere in REQUEST_URI this rule works best:
RewriteEngine On
RewriteCond %{THE_REQUEST} \s[^?]*//
RewriteRule ^.*$ /$0 [R=301,L,NE]
It takes advantage of the fact that mod_rewrite engine itself converts all multiple forward slashes to a single slash in the RewriteRule pattern. We use RewriteCond %{THE_REQUEST} to make sure original REQUEST_URI contains multiple slashes.
Here [^?]*// matches 2 // before matching query string since [^?] matches anything except ?. This will allow // in query string.
Try with:
RewriteCond %{REQUEST_URI} ^(.*?)//+$
RewriteRule ^ %1/ [R=301,L]
You htaccess works great as you can test on below link
https://htaccess.madewithlove.be/
So you need to make sure you test either with a Chrome Incognito window or using like below
curl -v http://example.com////
I usually prefer curl as I know it will give a fresh response from the server always
You just need two rule to match two different pattern
RewriteCond %{REQUEST_URI} ^(?:/){2,}$
RewriteRule . / [R=301,L]
RewriteCond %{REQUEST_URI} ^(.*?)(?:/){2,}$
RewriteRule . %1/ [R=301,L]

How this regex matches in htaccess

I am trying to add trailing slash to a url. I have my own logic to do so but found another one on stackoverflow (here). Now the regex in this line
RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]
apparently matches the RewriteRule for the url http://www.example.com/wp-admin.
What I first did was:
RewriteCond %{REQUEST_URI} /wp-admin$ [NC]
RewriteCond %{REQUEST_URI} !/+$
RewriteRule ^ %{ENV:proto}://%{HTTP_HOST}%{REQUEST_URI}/ [R=301,L]
So my question is how /wp-admin$ is similar to ^([_0-9a-zA-Z-]+/)?wp-admin$?
This is because leading slash is matched when you use RewriteCond %{REQUEST_URI} but current directory (relative to DocumentRoot) is stripped when you use a pattern in RewriteRule in .htaccess file, which is a per directory directive.
Hence a leading slash is not matched in RewriteRule but is matched in RewriteCond.

removing trailing backslashes moves to front of the subdirectory

I added this line to my .htaccess file to remove trailing backslashes:
RedirectMatch 301 ^(.*)/$ /$1
but it causes the backslash to move to the back of the sub-directory (in front of the domain).
so if I type: localhost/subfolder/
into the address bar and press enter the result is this:
localhost//subfolder
I have also tried
RewriteRule ^(.+)/$ /$1 [R=301,L]
but this had the same issue (and others). Anyone know why this happens.Thank you for reading
p.s. I am using apache2.4.4
Since URI in RedirectMatch starts with a leading slash, you can use this rule:
RedirectMatch 301 ^(.*)/$ $1
But better is to use mod_rewrite rule to exclude directories from this rule:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{THE_REQUEST} \s(.+?)/+[?\s]
RewriteRule ^ %1 [R=301,NE,L]

.htaccess regular expression need to make trailing forward slash optional

I need to include an optional trailing forwardslash, that's an /, in my RewriteRule
What I have so far is
RewriteRule ^([a-zA-Z0-9]+)$ u.php?$1|$2
Which works fine, for example http://foo.bar/abcde will redirect to http://foo.bar/u.php?abcde and handles any querystring parameters that may be present.
What I need to do is take http://foo.bar/abcde/ (with the trailing forwardslash) and redirect to http://foo.bar/u.php?abcde
So, if its present, I need remove the final forward slash from $1 in my RewriteRule. How do I do this? I'm new to apache and have tried many different regex rules but can't get it right.
Just put /? before the $ at the end in your pattern:
RewriteRule ^([a-zA-Z0-9]+)/?$ u.php?$1
But I would rather suggest you to allow just one spelling (either with or without trailing slash) and redirect the other one:
# remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*)/$ /$1 [L,R=301]
# add trailing slash
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .*[^/]$ /$0/ [L,R=301]