2

EDIT: As requested below, this is the entire ruleset for one product (obsolete now, as I should be able to consolidate these into ONE simple rule that looks for the productID#):

 RewriteRule  /mens-shirts-77/alice-in-wonderland-shirt-662.html$ http://www.domain.com/alice-in-wonderland-shirt-p160c3 [R=301]
 RewriteRule  /womens-shirts-92/womens-alice-in-wonderland-shirt-872.html$ http://www.domain.com/alice-in-wonderland-shirt-p160c3 [R=301]
 RewriteRule  /index.php?main_page=product_info*&products_id=(662|872)*$ http://www.domain.com/alice-in-wonderland-shirt-p160c3 [R=301]

And here's the original query string from above that I'm trying to wildcard down to just the productID:

/index.php?main_page=product_info&cPath=77&products_id=694&hipid=63ad73f32f5159a3d0f71b7b92404591

I would like to consolidate the three line rulesets above into a single line (the productID is always attached to any form of the URL, it's the ONLY thing I need to reference from any incoming URL)... this is my first shot, which I believe now is not going to be that easy, but you get the idea:

RewriteRule  *(662|872)*$ http://www.domain.com/alice-in-wonderland-shirt-p160c3 [R=301,L]

From what I understand now, I have to write out a regex that literally takes into consideration every single potential character in the URL's... but with that kind of overkill comes more potential for conflict... for example this rule works for the query string URL, but not the other two:

RewriteRule  ^/[A-Za-z.?_=&]+[0-9]+[A-Za-z.?_=&]+(662|872)[A-Za-z.?_=&]+[A-Za-z0-9._%+-]+  http://www.domain.com/alice-in-wonderland-shirt-p160c3 [R=301,L]

So is it even possible to build a single regex that will handle BOTH forms of URL's (query string AND rewritten) in one formula?

I'm familiar enough with regex to make something, but I'm not familiar enough to understand the right and wrong way to do things... this is for a long history SEO migration to a new platform... I have to get this expression right, and ideally consolidated down to it's most minimal form (there's 300 URL's with multiple incoming versions that need to be accounted for, as shown above)... I don't think I should have 1000 htaccess rules on an already graphic heavy ecommerce site. :/

Thanks for taking a look... I really need to get this right the first time!

  • Yes, it is better to consolidate your directives into as few as possible (using regex patterns), however, it doesn't look like what you have is "written properly" (* isn't simply a "wildcard"). Can you paste the complete rule and the URLs you want to redirect from (that is supposedly covered by this directive). – MrWhite Jun 21 '15 at 16:30
  • there are a few ways of handling large numbers of rewrites/redirects mentioned here httpd.apache.org/docs/2.2/rewrite/rewritemap.html you might want to benchmark against your own requirements for "ease of maintenance" and "efficiency". I personally found separate .conf files with a few .map files fine for 100s of rules. Server was not under heavy load however. – John McNamara Jun 21 '15 at 17:50
  • @john: I'm on a shared server, so no access to "rewritemaps" – JacksonJJ Jun 22 '15 at 18:42
  • @w3d: Updated the original question with more information... all I need to do is search the incoming URL for the product ID# (ALL other URL data can be ignored or wildcarded), then forward it to the associated new URL... given, each new URL has TWO old ProductID's that need to be consolidated, but it's not THAT complex of a scenario. Anyway, I obviously don't know what I'm doing, lol... just how detailed of a wildcard expression do I need to write to ignore everything except 3-digits? This is why I asked the question on here, I really don't understand the details of RegEx theory. – JacksonJJ Jun 22 '15 at 20:03
  • "I have to write out a regex that literally takes into consideration every single potential character in the URL's" - WOOO - HOLD IT RIGHT THERE! I think you've just invented a whole new level of complexity! - lol. Take a breath, read my answer and see what you think. Believe it or not, regex do make things simpler, not complex. :) – MrWhite Jun 22 '15 at 20:31
0

I see strange regex out there that appear to be more complex than necessary... for example, why use (.*) instead of just a *???

Because in regular expressions (as opposed to globbing patterns / standard wildcards) the * (asterisk) by itself does not mean anything. The * repeats the previous element 0 or more times. For example, the regex A* will match either nothing, "A", "AA" or "AAA", etc.

In your example *(662|872)*$, the first * is meaningless, it might even result in an error! The second * then repeats the previous element ("662" or "872") zero or more times. So, it will match "" (an empty string), "662", "872", "662662" or "662872", etc.

In fact, the regex you require is probably a lot simpler (not complex). For instance, (662|882) will match "662" or "882" anywhere in the string.

However, if you need to match both query strings and URL paths then this will add complexity as you can't do this with a single RewriteRule. You can't match the query string with the RewriteRule directive. You would need to do something like the following:

RewriteCond %{QUERY_STRING} products_id=(662|872) [OR]
RewriteCond %{REQUEST_URI} -(662|872)\.
RewriteRule ^ /alice-in-wonderland-shirt-p160c3 [R=301,L]

This assumes you are redirecting to the same domain, if not then you will obviously need the absolute URL in the RewriteRule substitution.

Is it even possible to build a single regex that will handle BOTH forms of URL's (query string AND rewritten) in one formula?

A single mod_rewrite directive - no.

However, do you really need to match the query string and the URL path? You state that one is "rewritten". Are users accessing the site with both URLs? If the URL has already been canonicalised then this could indeed be simplified, as you can simply ignore the query string version. Like so:

RewriteRule -(662|872)\. /alice-in-wonderland-shirt-p160c3 [R=301,L]

(The additional bits to the regex are just to ensure it doesn't match anywhere else in the URL. If you are sure "662" or "872" cannot appear anywhere else in the URL or part of another product id, then they can be removed.)

  • Thanks for the details man... yeah, I only need the expression to look for EITHER-OR when it comes to the ProductID#... I'm consolidating TWO different productID's into ONE new one... and yes, I believe the query string / URL path is entirely unnecessary (that's the reason I was trying to wildcard it out completely)... the expression is strictly about the ProductID#... any URL that comes in with the number (662) or (872), should forward to "alice-in-wonderland-shirt-p160c3"... that's it... anyway, I'll give it some testing... brb!! – JacksonJJ Jun 22 '15 at 20:40
  • Sorry, my comment above is misguided... I do need the querystring and URL path versions to be looked at (the old site won't be rewriting, but I still need to forward old bookmarks that used that rewrite)... I can't seem to get any querystring method to work tho, it keeps forwarding to the main page, not the "Alice" link (the URL path version works fine tho)... on a side note, can't we just ignore that it's a querystring URL and look for the 3-digit number the same as the URL path version? Three lines is just as bad as my original method, if not worse, since there's alternates to be processed. – JacksonJJ Jun 22 '15 at 21:24
  • Yes, it's not a great solution I'm afraid - there will be a lot of repetition - but there's not much you can do with .htaccess on a shared server. You can't "ignore that it's a querystring" - the RewriteRule pattern only matches against the URL-path, if you try to match against the query string it will never match. Your "original (three line) method" simply would not work for this reason. Whether 1000 directives will slow down your site is hard to tell - you'd have to try it! – MrWhite Jun 22 '15 at 21:54
  • However, there is an alternative... don't use .htaccess! You could do the redirection in your server-side language of choice. #1 Are you redirecting to a different domain? (I assume not.) #2 Would these "old" URLs normally trigger a 404? If so then this would probably be more efficient implemented as a "custom 404". Normal traffic to the new site (on the same server?) would not be affected. – MrWhite Jun 22 '15 at 21:58
  • I kinda figured the "ignore querystring" wouldn't work, just thought there may be a tweak forcing it to read as a txt path (since we only need the number)... the 404 idea is something I hadn't thought of, but I'm not certain that linkjuice will pass that way since it becomes a 2-step redirect... but honestly, most of the reason I'm holding onto the querystring aspect is for all the oddball social media stuff (like Pinterest) who manage to find the query URL... so I'll think I'll just redirect any querystring links to the main page... I think I'm good to go then, thanks for the help man! – JacksonJJ Jun 22 '15 at 23:16

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.