如何以独立于操作系统的方式规范/折叠 Python 中的路径或 URL?
题
我尝试使用 os.normpath
为了转换 http://example.com/a/b/c/../
到 http://example.com/a/b/
但它在 Windows 上不起作用,因为它确实将斜杠转换为反斜杠。
解决方案
以下是具体操作方法
>>> import urlparse
>>> urlparse.urljoin("ftp://domain.com/a/b/c/d/", "../..")
'ftp://domain.com/a/b/'
>>> urlparse.urljoin("ftp://domain.com/a/b/c/d/e.txt", "../..")
'ftp://domain.com/a/b/'
请记住 urljoin
考虑一个路径/目录直到最后 /
- 此后是文件名(如果有)。
另外,不要添加前导 /
到第二个参数,否则你将得不到预期的结果。
os.path
模块与平台相关,但对于仅使用斜杠而不使用 URL 的文件路径,您可以使用 posixpath,normpath
.
其他提示
两者都不 urljoin
也不 posixpath.normpath
正确地完成工作. urljoin
强迫你加入某些东西,并且不处理绝对路径或过多的路径 ..
正确。 posixpath.normpath
折叠多个斜杠并删除尾部斜杠,这两件事都是 URL 不应该做的事情。
以下函数完全解析 URL,同时处理 .
沙 ..
s,根据正确的方式 RFC 3986.
try:
# Python 3
from urllib.parse import urlsplit, urlunsplit
except ImportError:
# Python 2
from urlparse import urlsplit, urlunsplit
def resolve_url(url):
parts = list(urlsplit(url))
segments = parts[2].split('/')
segments = [segment + '/' for segment in segments[:-1]] + [segments[-1]]
resolved = []
for segment in segments:
if segment in ('../', '..'):
if resolved[1:]:
resolved.pop()
elif segment not in ('./', '.'):
resolved.append(segment)
parts[2] = ''.join(resolved)
return urlunsplit(parts)
然后您可以在完整的 URL 上调用它,如下所示。
>>> resolve_url("http://example.com/dir/../../thing/.")
'http://example.com/thing/'
有关解析 URL 时必须考虑的更多信息,请参阅 我之前写过关于这个主题的类似答案.
这os模块通过。 “ - os.path中是模块中的一个posixpath,或ntpath”,你的情况明确地使用posixpath
>>> import posixpath
>>> posixpath.normpath("/a/b/../c")
'/a/c'
>>>
不隶属于 StackOverflow