Apreche
Apreche

Reputation: 32869

Match all subdomains except one in mod_rewrite

Ok, so I'm doing a mod_rewrite, and I'm in a situation to where I need to match any subdomain except for one. It starts out looking like this.

RewriteCond %{HTTP_HOST} ^([^\.]+)\.example\.com$ [NC]

So that matches and captures a single subdomain, no periods. But let's say I don't want to match the submdomain named 'dog'. I tried to do this with a negative lookahead like so.

RewriteCond %{HTTP_HOST} ^((?!dog)[^\.]+)\.example\.com$ [NC]

This works, for the most part. dog.example.com no longer matches, which is good. However, doggies.example.com also no longer matches. That is not good.

I was able to fix this by using a negative lookahead combined with a negative look-behind like so.

RewriteCond %{HTTP_HOST} ^((?!dog)[^\.]+(?<!dog))\.example\.com$ [NC]

This works. It works perfectly, as far as I can tell. The thing is, I can't believe that is the best way to achieve this match. A lookahead and a look-behind? Really? What is the "correct" way to achieve an equivalent expression?

Upvotes: 3

Views: 3359

Answers (2)

Gumbo
Gumbo

Reputation: 655129

If you want to use a negative lookahead, you need to anchor the expression to the dot:

RewriteCond %{HTTP_HOST} ^((?!dog\.)[^.]+)\.example\.com$ [NC]

Otherwise anything that starts with dog wouldn’t be allowed.

The same applies to the negative lookbehind:

RewriteCond %{HTTP_HOST} ^([^\.]+(?<!^dog))\.example\.com$ [NC]

Anchoring it to the start of the string with ^ will ensure that something that just ends with dog like catdog will still be allowed.

Another solution similar to what Vinko Vrsalovic mentioned is to test what the first submatch holds:

RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com$ [NC]
RewriteCond %1 !^dog$

Upvotes: 9

Vinko Vrsalovic
Vinko Vrsalovic

Reputation: 340151

You can simplify things a lot using the negation operator of RewriteCond, like this:

RewriteCond %{HTTP_HOST} ^([^\.]+)\.mydomain\.com$ [NC]
RewriteCond %{HTTP_HOST} !^dog\. [NC]

Upvotes: 1

Related Questions