views:

372

answers:

4

I'm looking to write a regex for a file path that must start with some prefix. In this case it should start with '/tank/home/'. I also want to make sure that it contains no '/..' -- no jumping up to parent directories.

I spent a while fiddling around without coming up with anything quite right. I settled on using two regexes, the first which must match and the second which must not match:

'^/tank/home/'

'/\.\.(/.*)?$'

Does this do what I think it does? Is there an easier way?

This is in a bash script, for what it's worth.

+1  A: 

You could use a negative lookahead to make sure that there aren't any /.. in the string:

^(?!.*/\.\..*)/tank/home.*$
Amber
Very close, but not quite right. That doesn't match "/tank/home/..foo".
alberge
If it's really necessary that you be able to match ..foo, then something like this should probably work: `^(?!.*/\.\.(?:/.*|$))/tank/home.*$`
Amber
(Basically make the look-ahead only match if it's /../ or /.. at the end of the string.)
Amber
Thanks -- I hadn't used negative lookahead before.
alberge
A: 

You could use negative lookbehind too:

\/tank\/home\/([^\/]|?(<!\/..)\/)+$

Eric Nicholson
+2  A: 

You can expand Dav's regex to include an extra trailing slash:

^(?!.*/\.\./.*)/tank/home.*$

But... a better option might be to make sure that the result of the path is something that starts under /tank/home:

FILEPATH=$(readlink -f $YOURFILE)
[[ $FILEPATH =~ ^/tank/home/ ]] && echo "starts with /tank/home/"
Kaleb Pederson
Aha. I was wondering if there was something that did that.
alberge
+1  A: 
'^/tank/home(?!.*/\.\.(/|$))/'

matches /tank/home/foo..bar but not /tank/home/.. or /tank/home/foo/../bar

Lucky