How to capture groups in htaccess? - apache

I'm having a hard time capturing groups in htaccess with a 301 redirect.
My rule is RedirectMatch 301 ^/viewitems/([_\-a-zA-Z0-9]+)/([_\-a-zA-Z0-9]+) http://example.com/catalogsearch/result/?q=$2&dir=desc&order=relevance
but with a test url of
http://example.com/viewitems/underground-hardwar/manhole-cable-hooks
it builds a url that looks like this:
http://example.com/catalogsearch/result/?q=manhole-cable-hooks/viewitems/underground-hardwar/manhole-cable-hooksdir=desc/viewitems/underground-hardwar/manhole-cable-hooksorder=relevance
Apparently, replacing every & with every capture group. What is going on and what am I doing wrong?

Apache uses PCRE so I believe the unescaped & does what the perl does with $& which is, it holds the string of the last pattern matched, in this case:
/viewitems/underground-hardwar/manhole-cable-hooks
So what happens is that for each & it replaces it with the above.
That's why the & needs to be escaped to give you the desired result.
RedirectMatch 301 ^/viewitems/([^/]+)/([^/]+)/? /catalogsearch/result/?q=$2\&dir=desc\&order=relevance

Related

HTACCESS: Redirect to home page if invalid number in url

I am using APACHE server and I want to redirect the url to home page if third parameter is invalid number.
Code I have written is ::
RedirectMatch 302 ^/app/([a-zA-Z0-9_-]+)/([a-zA-Z_-]+)/?$ /
But its not working.
In short:
www.xyz/app/test/3434 :: should pass
www.xyz/app/test/best :: should fail
www.xyz/app/test/34kkk34 :: should fail
You want to redirect when the last part is not a number. Stated otherwise, redirect when there's a non digit somewhere. To get this, you must first match any character including digits.
^/app/[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]*[a-zA-Z_-][a-zA-Z0-9_-]*/?$
Since you don't use any parts of the request in the target URL, there's also no need to capture anything ().
If you don't care about the particular characters, you can simplify the regular expression and just use .* instead of [a-zA-Z0-9_-]*, e.g.
^/app/.+?/.*?[^0-9].*/?$
You can use this rule:
RedirectMatch 302 ^/app/[a-zA-Z0-9_-]+/[a-zA-Z_-]+/[0-9]+/?$ /

How to rewrite URLs in htaccess that end with recurring characters

I have changed web platforms and have old URLs that I cannot and do not want to match on the new platform where the old content is now living.
I have an array of old product URLs that all have '-p-' in the URL, followed by a string of numbers and ending in .html (osCommerce platform URLs).
I would like to know how to rewrite:
/x/[rest-of-url]-p-[random numbers].html
to
/x/[rest-of-url]
I would like the end result to look something like this:
http://www.shop.com/shop/versace-black-snakeskin-pony-hair-hobo-p-2214.html
redirects to:
http://www.shop.com/shop/versace-black-snakeskin-pony-hair-hobo
Does anyone know if this is doable in the htaccess file as a rewrite rule?
My managed hosting service providers BeepWeb answered my question.
RewriteRule ^/shop/(.*)-p-(.*).html$ http://www.shop.com/product/$1/ [R=302]
The first argument is the URI that you are matching. The (.) matches any characters. The second argument is the destination URL. The $1 corresponds to the first (.). $2 would be the second (.*), and so on... The [R=302] tells the rewrite to be a 302 redirect (use [R=301] for a 301 redirect).
Using the (.) is essentially like using a wildard. You can instead narrow this down by specifying which characters you want to match as opposed to all characters (instead of using (.) you could use ([abc]*) which would match only against a, b and c characters).
Also, be careful that you do not match other URLs unintentionally (i.e. you need to make sure that the pattern matches are unique to the URLs being rewritten).
If you need the source reference, see the following:
https://httpd.apache.org/docs/current/rewrite/intro.html
Thanks again to http://www.beepweb.com for their detailed response.
Hope it helps others.

htaccess multiple directory redirect

I would like to know how you can filter out a multiple list of URL, and redirect to a page .
Example:
www.domain.de/notuse/seite1.html
www.domain.de/dir1/notuse/seite1.html
www.domain.de/dir1/dir2/notuse/seite1.html
I want now " notuse " have filtered and since I am total beginner , I'm not sure if that is correct :
RedirectMatch permanent ^.+notuse/ http://www.domain.de/new-directory/index.html
What would you suggest?
change your regex patterns :
RedirectMatch ^/.*notuse/site1\.html$ http://domain.de/new-dir/index.html
.* matches any charecters zero more times, so here it would match /dir1/dir2 if present in Request_uri.

mod_rewrite rule gives 404 errors

I am having problems with mod_rewrite which is throwing me the same error 404 is as follows:
RewriteRule ^music.mp3?id=(.*)$ music.php?id= [L]
i need url /music.mp3?id=1 and real url /music.php?id=1
any idea??
I think something is misunderstood in the path RewriteRule
You can't match against the query string (everything after the ? in the URL) in a RewriteRule. But you're not really matching against it anyways, it looks like you just need to appended to your target URI, so:
RewriteRule ^music\.mp3$ music.php [L]
Should be good enough. Any query string parameters (like ?id=1) will automatically get appended at the end.
In your expression (the engine rule), what you want to say is:
"When the url starts with music.mp3?id=, take whatever is after the = and change the URL to music.php?id= and put the part after id="
In regular expressions the . character has special meaning. If you want to say "the dot character", and not give it special meaning, you need to escape it, but putting a \ behind it, like this:
^music\.mp3?id=(.*)$
#Jon Lin already gave you the other part, which is about query strings.

Redirect 301 from a Directory to a Single File

I'm having a bit of trouble figuring out something that should be simple. I want to 301 redirect everything in a directory to one single file in a new location.
In my .htaccess, I've already tried the following...
Redirect 301 /myDir/ http://www.mydomain.com/myNewDir/index.html
and this...
Redirect 301 /myDir/ http://www.mydomain.com/myNewDir/
and this...
Redirect 301 /myDir http://www.mydomain.com/myNewDir
The problem is that each of those are simply mapping each file within /myDir/, and appending it to the end of the destination URL.
After Googling, I saw something that said to do this...
Redirect 301 ^/myDir(.*) http://www.mydomain.com/myNewDir
But that just does the same thing... it's mapping the existing file location to the end of the URL.
It was easy finding lots of ".htaccess redirect" tutorials online but they seem to only show the obvious examples like 'one-to-one file mapping' or 'one-to-one directory mapping'. These tutorials also seem to neglect explaining the various relevant file directives and how to properly use them.
This particular hosting account is garbage and also has FrontPage extensions installed. Mod-rewrite fails (breaks the whole site) yet the Redirect 301 lines are operating fine. So until I can move this new (non-FrontPage) site to a more robust hosting account, I'll need to stick with the Redirect 301 one-liner.
How can I simply use a Redirect 301 to redirect everything within /myDir/ to the same single file located at /myNewDir/index.html? (I'd prefer using just /myNewDir/ if possible). Kindly explain, in detail, the file directives used in your solution.
UPDATE:
Previously accepted answer is not working.
Example:
RedirectMatch 301 /myDir1/(.*) http://mydomain.org/newpath/myDir1/index.html
...is giving a "Too many redirects occurred trying to open" error.
This is because /myDir1/(.*) is matching anyplace within the string so if the target URL contains /myDir1/ anywhere, not just the root, it will get redirected into a nasty loop.
See my own posted answer for correct solution.
I found the answer within one of my old projects.
Redirect 301 is all wrong for this. I really wanted RedirectMatch 301 instead.
RedirectMatch 301 ^/myDir/(.*) http://www.example.com/myNewDir/
Explanation(s):
http://httpd.apache.org/docs/1.3/mod/mod_alias.html#redirectmatch
"This directive is equivalent to Redirect, but makes use of standard
regular expressions, instead of simple prefix matching."
http://www.zytrax.com/tech/web/regex.htm
"The ^ (circumflex or caret) outside square brackets means look only at
the beginning of the target string, for example, ^Win will not find
Windows in STRING1 but ^Moz will find Mozilla."
and...
"The . (period) means any character(s) in this position, for example,
ton. will find tons, tone and tonneau but not wanton because it has no
following character."
and...
The * (asterisk or star) matches the preceding character 0 or more
times, for example, tre* will find tree (2 times) and tread (1 time)
and trough (0 times).
Try this:
RedirectMatch 301 /myDir/.* http://www.mydomain.com/myNewDir/index.html
Reference: http://httpd.apache.org/docs/1.3/mod/mod_alias.html#redirectmatch.
As far as brackets around .* are concerned, RedirectMatch uses standard regular expressions, which means that you can capture matched characters and use them in your redirect rule refferencing them as $1, $2, etc.
In regular expressions * means any number of repetitions of the previous character. . - denotes any character. So the combination .* says that this pattern match any number of any character. Hence * . * means that this pattern will match /myDir and /myDir/, and still /myDir/test.html. So * . * can also be used