7

I am trying to match all URIs that begin with #/tool_[a-z\-]+# except if it's followed by /public. Such as /tool_calculator or whatever.

For example, if the URI begins with /tool_store-front or /tool_store-front/anything-but-public then I want to redirect them to HTTPS. So, /tool_store-front/public would not redirect.

Here's what I have and it's not working

RewriteCond %{HTTPS} =off
RewriteCond %{REQUEST_URI} ^/?tool_[a-z-]+(?!/public.+) [OR]
RewriteCond %{REQUEST_URI} ^/?secure
RewriteCond %{REQUEST_URI} !^/?secure/public/info
RewriteRule ^(.*)$ https://www.example.org%{REQUEST_URI} [NC,L]
anubhava
  • 761,203
  • 64
  • 569
  • 643
Yes Barry
  • 9,514
  • 5
  • 50
  • 69

1 Answers1

6

You can also change your negative lookahead condition to this using a possessive quantifier:

RewriteCond %{HTTPS} =off
RewriteCond %{REQUEST_URI} ^/tool_[a-z-]++(?!/public) [NC,OR]
RewriteCond %{REQUEST_URI} ^/secure(?!/public/info) [NC]
RewriteRule ^ https://www.example.org%{REQUEST_URI} [NE,R=301,L]

You can also use this negative lookahead:

RewriteCond %{REQUEST_URI} ^/tool_[a-z-]+(?!.*/public) [NC,OR]

Problem in your condition ^/?tool_[a-z-]+(?!/public.+) is that regex engine is backtracking [a-z]+, one position before / to assert negative lookahead (?!/public.+) true.

anubhava
  • 761,203
  • 64
  • 569
  • 643
  • It worked. Thanks <3. But how is it that it's backtracking `[a-z]+` as you said? I didn't quite follow :'( – Yes Barry Mar 31 '17 at 21:43
  • 1
    [See this demo to understand better](https://regex101.com/r/Zipw5q/1) Check `regex debugger` link to understand backtracking part better. Once that is clear change regex to `^/tool_[a-z-]++(?!/public)` and now there will be no match and again check `regex debugger` – anubhava Mar 31 '17 at 21:50