Welcome to WebmasterWorld Guest from 18.232.99.123

Forum Moderators: Ocean10000 & phranque

Message Too Old, No Replies

htaccess redirect old to new url - adding a dash

htaccess

     
8:02 am on Dec 11, 2016 (gmt 0)

New User

5+ Year Member

joined:Apr 21, 2011
posts: 4
votes: 0


Hello

I'd like to redirect several hundred urls starting with years like this old url:
www.mydomain.com/mystore/19962001-my-blue-widgets

to this new format where years are separated by a dash:
www.mydomain.com/mystore/1996-2001-my-blue-widgets

Using regex in htaccess file. So only is difference is the dash separating years.

I've tried
RewriteRule ^/mystore/([0-9]{4})([0-9]{4})? www.mydomain.com/mystore/$1-$2 [R,L]

Thanks for your help
Sam
11:59 am on Dec 11, 2016 (gmt 0)

Administrator

WebmasterWorld Administrator phranque is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month

joined:Aug 10, 2004
posts:11716
votes: 211


I've tried

what response do you get when you try that?

your regular expression isn't going to do the job because you aren't capturing the trailing part of the url for the redirect (the -my-blue-widgets part).
you should specify the protocol (http: or https:) in the target.
if you want the redirect to be a 301 status code you must specify the R=301 flag.
12:55 pm on Dec 11, 2016 (gmt 0)

New User

5+ Year Member

joined:Apr 21, 2011
posts: 4
votes: 0


404 error.
Yes I'm not sure how to capture the trailing part after the years ... not sure it can be done even.

RewriteRule ^/mystore/([0-9]{4})([0-9]{4}).* http ://www.mydomain.com/mystore/$1-$2.* [R=301,L]
3:33 pm on Dec 11, 2016 (gmt 0)

New User

joined:Mar 17, 2016
posts: 14
votes: 3


what response do you get when you try that?


Nothing appears to happen. Because of the slash prefix on the RewriteRule pattern, it will fail to match in .htaccess.

In .htaccess, the directory-prefix is first removed from the URL-path that matches against the RewriteRule pattern. The directory-prefix always ends in a slash, so the URL-path never starts with a slash. ie. The pattern should start "^mystore/"

the trailing part after the years ... not sure it can be done even.


Why do you doubt that it can be done? You've already done the hard part - apply the same principle to the remainder of the URL.

Aside: It's easier to test with 302 (temporary) redirects and change to 301 (permanent) once you are happy it's working OK. (Or test with browser caching disabled.) 301s are cached by the browser - so can make testing problematic.
5:47 pm on Dec 11, 2016 (gmt 0)

New User

5+ Year Member

joined:Apr 21, 2011
posts: 4
votes: 0


But what I'm trying to do is only rewrite the first part (years) of the url ... sure I could do :

RewriteRule ^mystore/([0-9]{4})([0-9]{4})-my-blue-widgets http ://www.mydomain.com/mystore/$1-$2-my-blue-widgets [R,L]
(not sure that the new url redirect would work ... can you add after $1-$2 like that?

But I'm trying to cover multiple old urls which may be
http ://mydomain/mystore/20002010-my-red-widgets
http ://mydomain/mystore/19922002-her-green-widgets
http ://mydomain/mystore/20062009-their-black-cars
etc
with one rewrite rule

This is the bit I think isn't possible right with htaccess / regex ?
6:51 pm on Dec 11, 2016 (gmt 0)

New User

joined:Mar 17, 2016
posts: 14
votes: 3


You can hard-code it like that, but I get that you want to make this generic for multiple URLs that follow a similar pattern. You were close with your earlier suggestion:


RewriteRule ^/mystore/([0-9]{4})([0-9]{4}).* http ://www.mydomain.com/mystore/$1-$2.* [R=301,L]


What do you think the $1 and $2 refer to?

You can follow the same principle as you have done for the "two years" and the corresponding $1 and $2 backreferences. The $1 is a backreference to the first captured group ie. the first parenthesised subpattern, ([0-9]{4}) (the first year). The $2 is a backreference to the 2nd captured group (the 2nd year), and so on. Just make a 3rd capturing group by wrapping parentheses around .* and using the backreference $3. For example:


RewriteRule ^mystore/([0-9]{4})([0-9]{4})(.*) http://www.mydomain.com/mystore/$1-$2$3 [R=301,L]


You can play around tidying it up, being more specific with the regex etc, but that is basically it. You could alternatively write it as:


RewriteRule ^(mystore)/(\d{4})(\d{4})-(.+) /$1/$2-$3-$4 [R=301,L]


This is similar, but not quite the same.

The only significant differerence is that this forces "-<something>" after the years. Whereas the earlier regex is literally "<anything>" after the years. Personally, I think this is a bit more readable. $1 is now a backreference to "mystore" (I try to avoid repetitiion whenever I can). $2 is the first year. $3 is the second year and $4 is the remainder of the URL (after the hyphen). \d is a shorthand character for digits (the same as [0-9]). I also tend to avoid using absolute URLs in the substitution (unless absolutely necessary - no pun intended), although it is admittedly "safer" to keep the substitution absolute for external redirects.
6:58 pm on Dec 11, 2016 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member lucy24 is a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month

joined:Apr 9, 2011
posts:15706
votes: 813


^/mystore/([0-9]{4})([0-9]{4}).*

Is this rule lying loose in the config file? It can't be; the question said "htaccess". So with a leading / slash the rule would never execute at all.

You need to move one parenthesis (round bracket) in the pattern. That's all. There is absolutely no need for more than two captures, since all you're doing is changing
firstpartsecondpart
to
firstpart-secondpart
i.e.
(firstpart)(secondpart)
to
$1-$2
7:02 pm on Dec 11, 2016 (gmt 0)

New User

joined:Mar 17, 2016
posts: 14
votes: 3


@lucy24 - Yes, much simpler!
9:17 am on Dec 12, 2016 (gmt 0)

New User

5+ Year Member

joined:Apr 21, 2011
posts: 4
votes: 0


@w3dk, @lucy24 - thank you for explaining and simplifying ... I didn't know you could use backreferences like that.