Home > Back-end >  How to efficiently match a .htaccess RewriteRule for a complete word only if it's the last part
How to efficiently match a .htaccess RewriteRule for a complete word only if it's the last part

Time:01-24

I'm unsure how to word this request, so please bear with me as I explain with an example. I'll try to make it clear.

I wish to redirect a URL if it ends with one of two words, let's say foo or bar. It must match only as a complete word, so food or new-foo shouldn't match. The URL might end with a slash, so /foo and /foo/ are both valid.

Also, the word might be by itself at the beginning of the URL or at the end of a longer path.

Thus, any of the following should match, with or without a trailing slash:

https://example.com/foo
https://example.com/new/foo
https://example.com/bar
https://example.com/some/other/bar

But, none of the following should match (with or without a trailing slash):

https://example.com/foo-new
https://example.com/old-bar
https://example.com/bar/thud
https://example.com/plugh/foo/xyzzy

Clarification: It's OK if the word is repeated, e.g. the following should still redirect, because foo is at the end of the URL:

https://example.com/foo/new/foo

The best that I've managed to come up with is to use two redirects, the first checking for the word on its own, and the second checking for the word being the last part of a path:

RewriteRule ^(foo|bar)/?$ https://redirect.com/$1/ [last,redirect=permanent]
RewriteRule /(foo|bar)/?$ https://redirect.com/$1/ [last,redirect=permanent]

There will, eventually, be several words, not just the two…

RewriteRule ^(foo|bar|baz|qux|quux|corge|grault|garply)/?$ https://redirect.com/$1/ [last,redirect=permanent]
RewriteRule /(foo|bar|baz|qux|quux|corge|grault|garply)/?$ https://redirect.com/$1/ [last,redirect=permanent]

… so using two RewriteRule statements seems error-prone and possibly inefficient. Is there a way to combine the two RewriteRule statements into one? Or, maybe, you have a better idea? (I toyed with FilesMatch, but I was confused as to how to go about it.)

Thank you

CodePudding user response:

This probably is what you are looking for:

RewriteEngine on
RewriteRule (?:^|/)(foo|bar)/?$ https://example.com/$1/ [L,R=301]

(?:^|/) is a "non capturing group", so $1 still refers to what is captured by (foo|bar), while the whole expression matches a requested URL with only those words or with those words as final folder in a path sequence.

  • Related