在1个字符串上应用多个规则的最佳实践

时间:2015-03-28 16:58:00

标签: python

我将url作为字符串,需要对其应用多个规则。第一条规则是删除锚点,然后删除' ../'表示法,因为urljoin在某些情况下加入url不正确,最后删除了前导斜杠。现在我有这样的代码:

def construct_url(parent_url, child_url):
        url = urljoin(parent_url, child_url)
        url = url.split('#')[0]
        url = url.replace('../', '')
        url = url.rstrip('/')
        return url

但我不认为这是最好的做法。我认为它可以做得更简单。请问你能帮帮我吗?感谢。

1 个答案:

答案 0 :(得分:0)

不幸的是,没有太多可以使你的函数更简单,因为你正在处理一些非常奇怪的情况。

但是你可以通过使用Python的urlparse.urlsplit()将明确定义的组件中的URL拆分,进行处理并使用{{3}将其重新组合在一起,从而使其更加健壮 }:

from urlparse import urljoin
from urlparse import urlsplit
from urlparse import urlunsplit

def construct_url(parent_url, child_url):
    url = urljoin(parent_url, child_url)
    scheme, netloc, path, query, fragment = urlsplit(url)
    path = path.replace('../', '')
    path = path.rstrip('/')
    url = urlunsplit((scheme, netloc, path, query, ''))
    return url


parent_url = 'http://user:pw@google.com'
child_url = '../../../chrome/#foo'

print construct_url(parent_url, child_url)

输出:

http://user:pw@google.com/chrome

使用urlparse中的工具具有以下优势:您可以确切地知道处理操作的内容(在您的情况下是路径和片段),并且它处理所有内容,例如用户凭据,查询字符串,参数等。你。


注意:与我在评论中建议的内容相反,urljoin确实会对网址进行规范化:

>>> from urlparse import urljoin
>>> urljoin('http://google.com/foo/bar', '../qux')
'http://google.com/qux'

但它是严格遵循RFC 1808的。

来自urlparse.urlunsplit()

  

在具有明确定义的基本URL

的对象中      

基地:<URL:http://a/b/c/d;p?q#f>

     

[...]

     

解析器必须小心处理有更多的情况   相对路径".."段比其中的层次级别   基本URL的路径。请注意,".."语法不能用于更改   网址的<net_loc>

../../../g    = <URL:http://a/../g>
../../../../g = <URL:http://a/../../g>

因此,urljoin通过保留那些无关的../来做正确的事情,因此您需要通过手动处理将其删除。