Skip to content

Instantly share code, notes, and snippets.

@dannyroa
Last active December 11, 2015 10:49
Show Gist options
  • Save dannyroa/4589855 to your computer and use it in GitHub Desktop.
Save dannyroa/4589855 to your computer and use it in GitHub Desktop.
• all single dot components of the path must be removed. For example, "foo/./bar" should be normalized to "foo/bar". • all double dots components of the path must be removed, along with their parent directory. For example, "foo/bar/../baz" should be normalized to "foo/baz".
def normalize_file_path(path):
#assumptions: valid path does not start with '../' or '/..'
if path.startswith('../') or path.startswith('/..'):
return None
#normalize all the double dots first
double_dot_index = path.find('/..')
if double_dot_index > -1:
#get the parent dir
parent_dir_index = path.rfind('/', 0, double_dot_index)
#handle case if parent dir is on 1st level (e.g. foo/../bar)
if parent_dir_index == -1:
parent_dir_index = 0
#normalize by removing the parent dir & double dots
path_to_remove = path[parent_dir_index:double_dot_index+3]
path = path.replace(path_to_remove, '') #may remove multiple occurences but it's ok
#recurse function passing the modified path
return normalize_file_path(path)
#normalize the single dots next
dot_index = path.find('./')
if dot_index > -1:
#normalize by removing the single dot
path = path.replace(path[dot_index:dot_index+2], '')
#recurse function passing the modified path
return normalize_file_path(path)
#path is fully normalized
return path
paths = []
paths.append('foo/bar/../baz')
paths.append('foo/../bar/../baz')
paths.append('foo/./bar')
paths.append('foo/./bar1/./bar2')
paths.append('/./bar/baz')
paths.append('../foo')
paths.append('/../foo')
paths.append('./foo')
paths.append('/./foo')
for path in paths:
print '%s : %s' % (path.ljust(30, ' '), normalize_file_path(path))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment