Forum Moderators: phranque

Message Too Old, No Replies

Rewrite Regexp

         

rainborick

3:02 pm on Mar 21, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I'm trying to implement a rewrite to allow for organizing files by using the first letter of the file name as a part of a folder name. For example, a request for /foo.jpg should be rewritten to /images/fimages/foo.jpg. To begin, I need to special case file names that begin with 0-9 to the directory "1images". My code thusfar is:

RewriteCond %{REQUEST_URI} ^/([0-9])([A-Za-z0-9\-_+%])*\.jpg$
RewriteRule ^([0-9])(.*) /images/1images/$1$2 [L]

And then I plan to add:


RewriteCond %{REQUEST_URI} ^/([A-Za-z])([A-Za-z0-9\-_+%])*\.jpg$
RewriteRule ^([A-Za-z])(.*) /images/$1images/$1$2 [L]

to account for files that begin with A-Z.

I tested it locally, and it works OK, but I have a feeling I'm overlooking something. The original issue is that this client's site has tens of thousands of files in the root directory and it's a terrible load on the server. This is a bridge to a redesign, so it doesn't absolutely need to account for any possible future variations in file names. Those are pretty much fixed for now. Still, any comments or corrections would be very helpful. Thanks!

jdMorgan

3:39 pm on Mar 21, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I don't see any reason to use two rules instead of one (I don't see that your "special case" is special, based on a quick review). Also, you can dispense with your RewriteCond, and do all the work in the rule itself.

Note the nested parentheses ($1 now includes $2, simplifying the substitution), and the use of [NC] to make the pattern match case-insensitive, thus reducing the required number of range comparisons by one-third. The subpattern for the "filename" has also been simplified to accept anything other than a period or a slash, again for performance.

I also took the liberty of inserting a separator underscore in the /x_images subdirectory path to improve readability and avoid confusion during directory maintenance.


RewriteRule ^(([0-9a-z])[^./]+\.jpg)$ /images/$2_images/$1 [NC,L]

You could further simplify this and simply use "x" as the directory name, instead of "x_images", since the "images" part is redundant:

RewriteRule ^(([0-9a-z])[^./]+\.jpg)$ /images/$2/$1 [NC,L]

Note that the exclusion of "/" in the requested-filename subpattern combined with the fact that you're rewriting to a subdirectory is that only thing that keeps this rule from creating an "infinite" rewriting loop; Beware of that if you change this pattern.

Jim

jdMorgan

4:17 pm on Mar 21, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Update:

OK, I see where you're going with the "/1_images" directory. While I'd advise using a completely-consistent mapping approach, you could indeed do that with two rules:


RewriteRule ^([0-9][^./]+\.jpg)$ /images/1_images/$1 [L]
RewriteRule ^(([a-z])[^./]+\.jpg)$ /images/$2_images/$1 [NC,L]

Jim

[edited by: jdMorgan at 4:18 pm (utc) on Mar. 21, 2009]

rainborick

5:42 pm on Mar 21, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Thanks for the help. The special case was because I didn't want to create ten directories for the file names that started with a number. Your fix does address an issue I was worried about: the rule has to be limited to requests for files in the root directory. Thanks again!