5

There are a few similar questions on SO, but none that work for this specific scenario.

I want to replace all forward slashes in a URL path with dashes, using mod_rewrite.

So https://stackoverflow.com/foo/bar/baz should redirect to https://stackoverflow.com/foo-bar-baz.

There could be any number of segments in the path (between forward slashes).

I think the solution involves the N flag, but every attempt I've made results in an endless loop.

anubhava
  • 761,203
  • 64
  • 569
  • 643
ank
  • 53
  • 6

1 Answers1

5

You can use these 2 rules in your root .htaccess:

RewriteEngine On
RewriteBase /

RewriteRule ^([^/]+)/([^/]+)/?$ $1-$2 [NE,L,R=302]

RewriteRule ^([^/]+)/(.+)$ $1-$2

This will redirect example.com/foo/bar/baz/abc/xyz/123 to example.com/foo-bar-baz-abc-xyz-123

anubhava
  • 761,203
  • 64
  • 569
  • 643
  • this works perfectly - are you able to explain it, i.e. why the two steps? – ank Mar 14 '15 at 00:14
  • 1
    Yes sure. First rule will execute only when there is only forward slash to be replaced so will be skipped until last `/`. 2nd rule will keep executing multiple times replacing each `/` by `-` until one `/` is left. – anubhava Mar 14 '15 at 04:46
  • Why does the second one keep executing multiple times without the `N` flag? – ank Mar 15 '15 at 07:02
  • 1
    `N` is not needed for looping, that is default Apache behavior. As long as there is any matching rule for the current URI that rule will be executed. – anubhava Mar 15 '15 at 07:42
  • That's great thanks mate. Could you swap the rules? As the first one gets executed last? Or is it in that order for URLs with only one forward slash to replace? – ank Mar 15 '15 at 07:55
  • 1
    Ordering is important here. As soon an one slash is remaining a redirect should take place. – anubhava Mar 15 '15 at 09:48
  • Is it possible to rewrite without redirect? – SenG Sep 11 '16 at 10:08
  • Just remove `R=302` from above rule. – anubhava Sep 11 '16 at 16:14
  • 1
    Works for me. If you want example.com/directory/foo/bar/baz/abc/xyz/123 to direct to example.com/directory/foo-bar-baz-abc-xyz-123 just do RewriteRule ^([^/]+)/([^/]+)/?$ /directory/$1-$2 [NE,L,R=301] RewriteRule ^([^/]+)/(.+)$ /directory/$1-$2 -- That's how I have mine setup and it's working. 301 instead of 302 should permanently redirect search engines to the new URL – Michael d Apr 05 '17 at 17:02
  • how to do this in nginx? – Siwei Apr 26 '19 at 00:06