martinatime
martinatime

Reputation: 2487

How do I create a recursive replacement in mod_rewrite?

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?

Upvotes: 1

Views: 843

Answers (2)

chaos
chaos

Reputation: 124297

Try this:

RewriteRule (.*)/(.+) $1_$2 [NS]
RewriteRule (.*) stuff/$1 [NS]

Upvotes: 1

David Z
David Z

Reputation: 131600

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.

Upvotes: 4

Related Questions