Jump to content

Negative Lookbehind


Drongo_III
 Share

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

Link to comment
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.

Link to comment
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.

Link to comment
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.

Link to comment
Share on other sites

This thread is more than a year old.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

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.