4

How to do this with regular expression?

Old -> New
http://www.example.com/cat1/cat2/cat3/tool-model-10   -> http://www.example.com/tool/tool-model-10
http://www.example.com/cat1/cat2/cat4/tool-model-11   -> http://www.example.com/tool/tool-model-11
http://www.example.com/cat1/cat2/tool-model-12        -> http://www.example.com/tool/tool-model-12
http://www.example.com/cat5/cat6/tool-model-13        -> http://www.example.com/tool/tool-model-13
http://www.example.com/cat7/tool-model-14             -> http://www.example.com/tool/tool-model-14

I've tried this:

Redirect 301 /cat1/cat2/cat3/tool-model-10 http://www.example.com/tool/tool-model-10
Redirect 301 /cat1/cat2/cat4/tool-model-11 http://www.example.com/tool/tool-model-11 
Redirect 301 /cat1/cat2/tool-model-12      http://www.example.com/tool/tool-model-12 
Redirect 301 /cat5/cat6/tool-model-13      http://www.example.com/tool/tool-model-13
Redirect 301 /cat7/tool-model-14           http://www.example.com/tool/tool-model-14

I understand that logiс should be:

  1. divide URL string on 2 strings: 1 and 2
  2. If first URL string 1 contains tool-model- at the end AND does not contain tool catalog at the beginning then make redirect to http://www.example.com/tool/tool-model- PLUS two digits (string 2).
  • "I've tried this" - And what was the problem with that? Did it do anything? Did you get an error? Where did you try it? ...or are you wanting to combine these rules into a single directive? – MrWhite Sep 4 '16 at 17:11
  • It is working, but when there are 20 models + structure of catalogs changed several times I got 100 lines with standard redirect like Redirect 301 /old-cat/tool-model-15 example.com/tool/tool-model-15 instead of 2-3 lines with regexp for all. So I want to combine in single directive. – Pretzel Sep 4 '16 at 17:17
1

If first url string 1 contain "tool-model-" at the end AND does not contain "tool" catalog at the beginning make redirect to http://www.example.com/tool/tool-model- PLUS two digits (string 2)

To simplify/combine your redirects into a single ruleset I would use mod_rewrite, rather than mod_alias (Redirect or RedirectMatch) since you want a condition that says does not contain "tool" (which is tricky with RedirectMatch). Try something like the following in your root .htaccess file:

RewriteEngine On
RewriteCond %{REQUEST_URI} !^/tool/
RewriteRule /(tool-model-\d\d)$ /tool/$1 [R=302,L]

This states for any URL that ends /tool-model-NN and does not start /tool/ then redirect to /tool/tool-model-NN. $1 in the substitution is a backreference to the captured group (ie. (tool-model-\d\d)) in the RewriteRule pattern (a regex).

NB: I've used a 302 (temporary) redirect above. Change this to 301 (permanent) when you are sure it's working OK. 301 redirects are cached by the browser, so can make testing awkward. (So, you will need to clear your browser cache before testing the above directives.)

Also, if you are currently using mod_alias Redirect (or RedirectMatch) for other redirects then it would be advisable to also convert these to mod_rewrite RewriteRule directives. The reason being that different modules run at different times, regardless of the order in the .htaccess file. So, you can get some unexpected conflicts by combining redirects from both modules.

  • Thank you, @w3dk. If I want to add comparison of the end URL with "tool-model-\d\d" is it correct: codeRewriteEngine On RewriteCond %{REQUEST_URI} /(tool-model-\d\d)$ RewriteCond %{REQUEST_URI} !^/tool/ RewriteRule /(tool-model-\d\d)$ /tool/$1 [R=302,L]code – Pretzel Sep 11 '16 at 7:39
  • Sorry, I'm not sure what you are trying to achieve with that last bit of code? It's valid, but it's really no different to the code I posted above, except that the RewriteCond directive you added is superfluous (that RewriteCond directive does the same as what the RewriteRule pattern does). (?) – MrWhite Sep 11 '16 at 8:56
  • NB: I am a newbie in regexp. I used added RewriteCond directive for speedup. For example if URL does not contain (tool-model-\d\d) interpreter should look more this block of code, go to next. May be I am not rigth because win in time too small. Just only for time and resources economy – Pretzel Sep 11 '16 at 9:10
  • 1
    Ah OK. However, mod_rewrite does not work like that. The RewriteRule directive is actually processed first. Only when the RewriteRule pattern matches the URL-path do the preceding RewriteCond directives get processed. (This is not a regexp thing, but a mod_rewrite thing.) So, the additional RewriteCond would actually be a "slow-down" (if anything), not a "speedup". Although, as you suggest, any difference in timing in this respect is likely to be "too small" to notice - in this instance anyway. – MrWhite Sep 11 '16 at 14:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.