从字符串中删除重复出现的(重叠的)斜杠
Remove recurrent (overlapping) slashes from string
我正在像这样解析 URLS
>>> from urllib.parse import urlparse
>>> urlparse('http://foo.bar/path/to/heaven')
ParseResult(scheme='http', netloc='foo.bar', path='/path/to/heaven', params='', query='', fragment='')
假设我有一个 URL 有一个格式错误的路径,循环 /
像这样:
>>> x = urlparse('http://foo.bar/path/to/////foo///baz//bar'))
ParseResult(scheme='http', netloc='foo.bar', path='/path/to/////foo///baz//bar', params='', query='', fragment='')
如您所见,x.path
仍然包含重复出现的斜线,我正在尝试删除它们,所以我尝试像这样拆分、循环和替换:
>>> newpath = x.path.split('/')
['', 'path', 'to', '', '', '', '', 'foo', '', '', 'baz', '', 'bar']
>>> for i in newpath:
if i == '':
newpath.remove('')
>>> '/'.join(newpath)
'/path/to/foo/baz/bar'
这提供了所需的输出,但我认为此解决方案效率低下而且很垃圾。我怎样才能做得更好?
这就是正则表达式的用途:
import regex as re
url = "http://foo.bar/path/to/////foo///baz//bar"
rx = re.compile(r'(?:(?:http|ftp)s?://)(*SKIP)(*FAIL)|/+')
url = rx.sub('/', url)
print(url)
这会产生
http://foo.bar/path/to/foo/baz/bar
参见 a demo on regex101.com。唯一真正的问题是在协议中保留任何双正斜杠,因此更新的 regex
模块和 (*SKIP)(*FAIL)
。您可以在 re
模块中使用 lookbehinds 实现相同的功能。
import re
s = 'http://foo.bar/path/to/////foo///baz//bar'
s = re.sub(r'(?<!:)/{2,}', '/', s)
print(s)
打印:
http://foo.bar/path/to/foo/baz/bar
编辑:编译正则表达式:
import re
s = 'http://foo.bar/path/to/////foo///baz//bar'
r = re.compile(r'(?<!:)/{2,}')
s = r.sub('/', s)
print(s)
您不应修改正在迭代的列表。参见 strange result when removing item from a list
您可以使用列表理解来创建没有所有 ''
元素的列表。
newpath = [s in x.path.split('/') if s != '']
'/'.join(newpath)
我正在像这样解析 URLS
>>> from urllib.parse import urlparse
>>> urlparse('http://foo.bar/path/to/heaven')
ParseResult(scheme='http', netloc='foo.bar', path='/path/to/heaven', params='', query='', fragment='')
假设我有一个 URL 有一个格式错误的路径,循环 /
像这样:
>>> x = urlparse('http://foo.bar/path/to/////foo///baz//bar'))
ParseResult(scheme='http', netloc='foo.bar', path='/path/to/////foo///baz//bar', params='', query='', fragment='')
如您所见,x.path
仍然包含重复出现的斜线,我正在尝试删除它们,所以我尝试像这样拆分、循环和替换:
>>> newpath = x.path.split('/')
['', 'path', 'to', '', '', '', '', 'foo', '', '', 'baz', '', 'bar']
>>> for i in newpath:
if i == '':
newpath.remove('')
>>> '/'.join(newpath)
'/path/to/foo/baz/bar'
这提供了所需的输出,但我认为此解决方案效率低下而且很垃圾。我怎样才能做得更好?
这就是正则表达式的用途:
import regex as re
url = "http://foo.bar/path/to/////foo///baz//bar"
rx = re.compile(r'(?:(?:http|ftp)s?://)(*SKIP)(*FAIL)|/+')
url = rx.sub('/', url)
print(url)
这会产生
http://foo.bar/path/to/foo/baz/bar
参见 a demo on regex101.com。唯一真正的问题是在协议中保留任何双正斜杠,因此更新的 regex
模块和 (*SKIP)(*FAIL)
。您可以在 re
模块中使用 lookbehinds 实现相同的功能。
import re
s = 'http://foo.bar/path/to/////foo///baz//bar'
s = re.sub(r'(?<!:)/{2,}', '/', s)
print(s)
打印:
http://foo.bar/path/to/foo/baz/bar
编辑:编译正则表达式:
import re
s = 'http://foo.bar/path/to/////foo///baz//bar'
r = re.compile(r'(?<!:)/{2,}')
s = r.sub('/', s)
print(s)
您不应修改正在迭代的列表。参见 strange result when removing item from a list
您可以使用列表理解来创建没有所有 ''
元素的列表。
newpath = [s in x.path.split('/') if s != '']
'/'.join(newpath)