Jump to content
Sign in to follow this  
Drongo_III

Negative Lookbehind

Recommended Posts

Hi Guys

 

Stuck on what is probably a very easy thing.

 

I'm adding wildcard route to an application and I'm using regex to match anything UNLESS it's preceded by /admin/ in which case I don't want the match to succeed.

 

I want to match: /foo/bar/

 

I don't want to match: /admin/foo/bar  

 

I figured this was a job for Negative Lookbehind but it doesn't work when I follow the lookbehind with a character class like so:

^\/(?<!admin)[a-z0-9\-\/]*

This doesn't work as /admin/test/ still matches the full string - even though I would expect anything following the word 'admin' to fail.

 

So either you cannot use a character class after a lookbehind, or I'm doing it wrong.  Any advice would be most welcome!

 

Drongo

Share this post


Link to post
Share on other sites

You first consume a slash, and then you check if the previous characters aren't “admin”. Since a slash isn't “admin”, that whole check if obviously always true.

 

Why do you even want a lookbehind? Just use a lookhead to exclude paths starting with “/admin”, then match all other paths

$path_pattern = '~\\A(?!/admin)/[a-z\\d/-]*~';

Note that you're going to exclude paths like “/administrative_leave” which just happen to start with “/admin” as well, which may or may not be what you want.

 

I any case, I would strongly recommend you avoid complex regex gymnastics which even you as the application author barely understand. Keep it simple. Admin pages in particular should be on a separate (sub)domain, because then you can properly isolate them from the public site.

Share this post


Link to post
Share on other sites

Thanks for the reply Jacques.

 

I'll certainly give your advice some consideration. Out of interest though, and in an effort to understand lookbehinds more, can u answer me:

 

1) is it possible to follow a lookbehind with a character class? Or is this not permitted?

 

2) what do you mean when you say the regex I've used will always be true. Doesn't that regex mean 'match a slash, then match anything that is not precedes by admin'? Therefore /admin/somepage shouldn't match. I say this because I thought lookbehinds acted at the point where they are defined so in my example why does the opening slash have any impact on the lookbehind and the expression that follows it?

 

Thanks,

 

Drongo

 

You first consume a slash, and then you check if the previous characters aren't “admin”. Since a slash isn't “admin”, that whole check if obviously always true.

 

Why do you even want a lookbehind? Just use a lookhead to exclude paths starting with “/admin”, then match all other paths

$path_pattern = '~\\A(?!/admin)/[a-z\\d/-]*~';
Note that you're going to exclude paths like “/administrative_leave” which just happen to start with “/admin” as well, which may or may not be what you want.

 

I any case, I would strongly recommend you avoid complex regex gymnastics which even you as the application author barely understand. Keep it simple. Admin pages in particular should be on a separate (sub)domain, because then you can properly isolate them from the public site.

Share this post


Link to post
Share on other sites

1) is it possible to follow a lookbehind with a character class?

 

Of course. Why shouldn't it be possbile?

 

 

 

2) what do you mean when you say the regex I've used will always be true. Doesn't that regex mean 'match a slash, then match anything that is not precedes by admin'? Therefore /admin/somepage shouldn't match. I say this because I thought lookbehinds acted at the point where they are defined so in my example why does the opening slash have any impact on the lookbehind and the expression that follows it?

 

Lookbehinds check the substring left of the current location. So in your case, the parser first consumes the slash, then it looks to the left to see if there's “admin”, but that's never the case, because there's a slash.

 

Regex parsers read the input from left to right, so “behind” means left and “ahead” means right.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.