我有以下代码:
url = 'abcdc.com'
print(url.strip('.com'))
我以为是abcdc
我得到:abcd
现在我知道了
url.rsplit('.com', 1)
有没有更好的办法?
参见.strip/.rstrip/。lstrip字符串方法在Python中工作?对于第一次尝试的具体解释。
我有以下代码:
url = 'abcdc.com'
print(url.strip('.com'))
我以为是abcdc
我得到:abcd
现在我知道了
url.rsplit('.com', 1)
有没有更好的办法?
参见.strip/.rstrip/。lstrip字符串方法在Python中工作?对于第一次尝试的具体解释。
当前回答
import re
def rm_suffix(url = 'abcdc.com', suffix='\.com'):
return(re.sub(suffix+'$', '', url))
我想重复一下这个答案,作为最具表现力的回答。当然,以下操作会占用更少的CPU时间:
def rm_dotcom(url = 'abcdc.com'):
return(url[:-4] if url.endswith('.com') else url)
但是,如果CPU是瓶颈,为什么要用Python编写呢?
CPU什么时候会成为瓶颈?在驾驶方面,可能是这样。
使用正则表达式的优点是代码可重用性。如果你接下来想要移除。Me ',只有三个字?
同样的代码可以做到这一点:
>>> rm_sub('abcdc.me','.me')
'abcdc'
其他回答
url[:-4]怎么样?
如果你确定字符串只出现在末尾,那么最简单的方法是使用'replace':
url = 'abcdc.com'
print(url.replace('.com',''))
因为似乎还没有人指出这一点:
url = "www.example.com"
new_url = url[:url.rfind(".")]
这应该比使用split()的方法更有效,因为不会创建新的列表对象,而且这种解决方案适用于带有几个点的字符串。
import re
def rm_suffix(url = 'abcdc.com', suffix='\.com'):
return(re.sub(suffix+'$', '', url))
我想重复一下这个答案,作为最具表现力的回答。当然,以下操作会占用更少的CPU时间:
def rm_dotcom(url = 'abcdc.com'):
return(url[:-4] if url.endswith('.com') else url)
但是,如果CPU是瓶颈,为什么要用Python编写呢?
CPU什么时候会成为瓶颈?在驾驶方面,可能是这样。
使用正则表达式的优点是代码可重用性。如果你接下来想要移除。Me ',只有三个字?
同样的代码可以做到这一点:
>>> rm_sub('abcdc.me','.me')
'abcdc'
如果你需要剥离字符串的某一端,如果它存在,否则什么都不做。我最好的解决方案。您可能会想使用前两个实现中的一个,但是为了完整性,我已经包括了第三个实现。
对于常量后缀:
def remove_suffix(v, s):
return v[:-len(s)] if v.endswith(s) else v
remove_suffix("abc.com", ".com") == 'abc'
remove_suffix("abc", ".com") == 'abc'
对于正则表达式:
def remove_suffix_compile(suffix_pattern):
r = re.compile(f"(.*?)({suffix_pattern})?$")
return lambda v: r.match(v)[1]
remove_domain = remove_suffix_compile(r"\.[a-zA-Z0-9]{3,}")
remove_domain("abc.com") == "abc"
remove_domain("sub.abc.net") == "sub.abc"
remove_domain("abc.") == "abc."
remove_domain("abc") == "abc"
对于常量后缀的集合,对于大量调用的渐近最快的方法:
def remove_suffix_preprocess(*suffixes):
suffixes = set(suffixes)
try:
suffixes.remove('')
except KeyError:
pass
def helper(suffixes, pos):
if len(suffixes) == 1:
suf = suffixes[0]
l = -len(suf)
ls = slice(0, l)
return lambda v: v[ls] if v.endswith(suf) else v
si = iter(suffixes)
ml = len(next(si))
exact = False
for suf in si:
l = len(suf)
if -l == pos:
exact = True
else:
ml = min(len(suf), ml)
ml = -ml
suffix_dict = {}
for suf in suffixes:
sub = suf[ml:pos]
if sub in suffix_dict:
suffix_dict[sub].append(suf)
else:
suffix_dict[sub] = [suf]
if exact:
del suffix_dict['']
for key in suffix_dict:
suffix_dict[key] = helper([s[:pos] for s in suffix_dict[key]], None)
return lambda v: suffix_dict.get(v[ml:pos], lambda v: v)(v[:pos])
else:
for key in suffix_dict:
suffix_dict[key] = helper(suffix_dict[key], ml)
return lambda v: suffix_dict.get(v[ml:pos], lambda v: v)(v)
return helper(tuple(suffixes), None)
domain_remove = remove_suffix_preprocess(".com", ".net", ".edu", ".uk", '.tv', '.co.uk', '.org.uk')
最后一个在pypy中可能比在cpython中快得多。对于几乎所有不涉及大量潜在后缀字典的情况(至少在cPython中无法轻松表示为regex), regex变体可能比这个更快。
在PyPy中,regex变体对于大量调用或长字符串几乎肯定更慢,即使re模块使用DFA编译regex引擎,因为lambda的绝大多数开销将由JIT优化。
然而,在cPython中,在几乎所有情况下,你为正则表达式运行的c代码的比较几乎肯定超过了后缀集合版本的算法优势。
编辑:https://m.xkcd.com/859/