0

I have a rewrite condition that rewrites /myPage.php?myQueryVar=foo-aRandomString to /myNewPage/foo-aRandomString. I only want this to apply in instances where there is a hyphen in the query value therefore I have some conditions in place as seen below:

RewriteCond %{QUERY_STRING} (^|&)myQueryVar=foo-(.*)($|&)
RewriteCond %{THE_REQUEST} ^GET\ /myPage\.php\?myQueryVar=([^\s&]+) [NC]
RewriteRule ^myPage\.php$ /myNewPage/%1? [R=301,L]

I'd like to add another rule exception allowing /myPage.php?myQueryVar=bar-aRandomString. Currently I've had to simply cloine the above code and use it again but changing foo to bar as sen below. Is there a cleaner way of doing this without having to have multiple line of near identical code? Thank you.

RewriteCond %{QUERY_STRING} (^|&)myQueryVar=bar-(.*)($|&)
RewriteCond %{THE_REQUEST} ^GET\ /myPage\.php\?myQueryVar=([^\s&]+) [NC]
RewriteRule ^myPage\.php$ /myNewPage/%1? [R=301,L]
steve
  • 471
  • 6
  • 15
  • The final rewriterule is exactly the same in both cases? – Julio Sep 01 '20 at 08:40
  • @Julio Yes the final rewrite rule is the same, but the query variable that is passed will be different. This rewrite rule is only executed if the above conditions are met. As the first example contains `foo` that rewrite rule is only executed the `foo` is present. – steve Sep 01 '20 at 08:54
  • What about using `RewriteCond %{QUERY_STRING} (^|&)myQueryVar=(foo|bar)-(.*)($|&)` instead of your first rewriteCond? – Julio Sep 01 '20 at 08:56
  • @Julio thanks a lot that works. If you put it as the answer i'll mark it as correct as it may help others in the future. – steve Sep 01 '20 at 09:09
  • @Julio He doesn't need to capture foo or bar, so use a non capturing group instead. https://stackoverflow.com/questions/3512471/what-is-a-non-capturing-group-in-regular-expressions – Genu Sep 01 '20 at 09:32
  • I'm pretty sure he didn't want to capture `($|&)` and `(^|&)` either :). I'll add an explanation of no capturing groups on my answer – Julio Sep 01 '20 at 09:35
  • @steve, I added my answer with the explanations – Julio Sep 01 '20 at 10:28

1 Answers1

0

Try to use this:

RewriteCond %{QUERY_STRING} (^|&)myQueryVar=(foo|bar)-(.*)($|&)
RewriteCond %{THE_REQUEST} ^GET\ /myPage\.php\?myQueryVar=([^\s&]+) [NC]
RewriteRule ^myPage\.php$ /myNewPage/%1? [R=301,L]

(The first RewriteCond was changed)

Basically, foo was changed to this (foo|bar) which means:

(        # begin of group
    foo  # a literal 'foo'
   |     # or
    bar  # a literal 'bar'
)        # end of group

Bear in mind we had to enclose the two options within a group, since if not, the regex would have meant instead:

(^|&)myQueryVar=foo|bar-(.*)($|&) ==> (^|&)myQueryVar=foo OR bar-(.*)($|&)

Also, if you don't want to capture what is inside the parenthesis (that's why they are called 'capturing groups') You may use 'non-capturing groups' instead (?:). Using non-capturing groups is a good practice if you don't actually need to capture the inner data.

Also, you don't need the group holding the .* on the first RewriteCond, since you really use the capturing group of the second RewriteCond

So the rules could be changed like this:

RewriteCond %{QUERY_STRING} (?:^|&)myQueryVar=(?:foo|bar)-.*(?:$|&)
RewriteCond %{THE_REQUEST} ^GET\ /myPage\.php\?myQueryVar=([^\s&]+) [NC]
RewriteRule ^myPage\.php$ /myNewPage/%1? [R=301,L]

But even so, you could just one one single RewriteCond by joining the two regexes:

RewriteCond %{THE_REQUEST} ^GET\ /myPage\.php\?myQueryVar=((?:foo|bar)-[^\s&]+) [NC]
RewriteRule ^myPage\.php$ /myNewPage/%1? [R=301,L]

(note that the (?:foo|bar)is a non-capturing group, since you don't need to capture just that part, you need to capture the variable as a whole

Julio
  • 5,208
  • 1
  • 13
  • 42