views:

310

answers:

2

I'm fairly new to mod_rewrite and I am attempting to convert a URL from

http://example.com/foo/bar/blah/etc.html

into

http://example.com/stuff/foo_bar_blah_etc.html

The assumption is that there is not a set number of directories between the domain and the file name therefore I cannot just write a single rewrite rule with 3 placeholders. I could conceivably create 5 or 6 rules with zero to 5 placeholders but I have a feeling there is a better way. Can someone please help me with this?

+1  A: 

Try this:

RewriteRule (.*)/(.+) $1_$2 [NS]
RewriteRule (.*) stuff/$1 [NS]
chaos
Thanks for the quick response. Once I have a chance to test it I will accept your answer.
martinatime
What I originally posted doesn't work, I'm afraid. I've edited it to something that testing shows more functional.
chaos
I think you meant to use [N] for the flags for the first line.
martinatime
+2  A: 

I think you could do this to replace one slash at a time with an underscore:

RewriteRule ^/(.+)/(.*?)$ /$1_$2 [N]
RewriteRule ^.*$ /stuff$0

The [N] flag causes Apache to restart the URL rewriting process from the first rule. If you have other rules that apply to the URL before these two, remember that they'll be invoked on every iteration as well.

An alternative, which may or may not be more efficient, would be to use an external program to handle the rewriting. You'd put this in your Apache configuration file (instead of the above)

RewriteMap slashtouscore prg:/usr/local/bin/slashtouscore.pl
RewriteRule ^/(.*)$ /stuff${slashtouscore:$1}

and then you'd need to create the executable script /usr/local/bin/slashtouscore.pl with the contents

#!/usr/bin/perl
$| = 1;
while (<>) {
    s|/|_|g;
    print;
}

(It doesn't have to be a Perl script, of course, any program with the same function will do - and of course the filename can be whatever you want, as long as it's accessible to Apache)

Note that none of this is tested.

David Zaslavsky
Thanks for the thorough answer.
martinatime