Eu tenho o seguinte código:
url = 'abcdc.com'
print(url.strip('.com'))
Eu esperava: abcdc
Eu tenho: abcd
Agora eu faço
url.rsplit('.com', 1)
Existe uma maneira melhor?
Eu tenho o seguinte código:
url = 'abcdc.com'
print(url.strip('.com'))
Eu esperava: abcdc
Eu tenho: abcd
Agora eu faço
url.rsplit('.com', 1)
Existe uma maneira melhor?
Respostas:
strip
não significa "remover esta substring". x.strip(y)
trata y
como um conjunto de caracteres e retira todos os caracteres desse conjunto dos fins de x
.
Em vez disso, você pode usar endswith
e fatiar:
url = 'abcdc.com'
if url.endswith('.com'):
url = url[:-4]
Ou usando expressões regulares :
import re
url = 'abcdc.com'
url = re.sub('\.com$', '', url)
url = url[:-4] if any(url.endswith(x) for x in ('.com','.net')) else url
EXAMLPLE.COM
nomes de domínio não diferenciam maiúsculas de minúsculas. (Este é um voto para a solução regex)
rsplit()
solução não tem o mesmo comportamento que a endswith()
string original não possui a substring no final, mas em algum lugar no meio. Por exemplo: "www.comeandsee.com".rsplit(".com",1)[0] == "www.comeandsee"
mas"www.comeandsee.net".rsplit(".com",1)[0] == "www"
s[:-n]
tem uma ressalva: pois n = 0
, isso não retorna a string com os últimos zero caracteres cortados, mas a string vazia.
Se você tem certeza de que a string aparece apenas no final, a maneira mais simples seria usar 'replace':
url = 'abcdc.com'
print(url.replace('.com',''))
www.computerhope.com
. faça uma verificação com endswith()
e deve ficar bem.
def strip_end(text, suffix):
if not text.endswith(suffix):
return text
return text[:len(text)-len(suffix)]
return text[:-len(suffix)]
Como parece que ninguém apontou isso ainda:
url = "www.example.com"
new_url = url[:url.rfind(".")]
Isso deve ser mais eficiente do que os métodos utilizados, split()
pois nenhum novo objeto de lista é criado e esta solução funciona para cadeias de caracteres com vários pontos.
Depende do que você sabe sobre o seu URL e exatamente o que você está tentando fazer. Se você souber que sempre terminará em '.com' (ou '.net' ou '.org'),
url=url[:-4]
é a solução mais rápida. Se for um URL mais geral, é melhor procurar na biblioteca urlparse que acompanha o python.
Se você, por outro lado, simplesmente deseja remover tudo após o final '.' em uma corda então
url.rsplit('.',1)[0]
vai funcionar. Ou se você quiser apenas quer tudo até o primeiro '.' Então tente
url.split('.',1)[0]
Em uma linha:
text if not text.endswith(suffix) or len(suffix) == 0 else text[:-len(suffix)]
Que tal url[:-4]
?
.ca
ou um .co.uk
URL.
Para urls (como parece fazer parte do tópico pelo exemplo dado), pode-se fazer algo assim:
import os
url = 'http://www.stackoverflow.com'
name,ext = os.path.splitext(url)
print (name, ext)
#Or:
ext = '.'+url.split('.')[-1]
name = url[:-len(ext)]
print (name, ext)
Ambos produzirão:
('http://www.stackoverflow', '.com')
Isso também pode ser combinado str.endswith(suffix)
se você precisar apenas dividir ".com" ou qualquer coisa específica.
url.rsplit ('. com', 1)
não está certo.
O que você realmente precisa escrever é
url.rsplit('.com', 1)[0]
, e parece IMHO bastante sucinto.
No entanto, minha preferência pessoal é essa opção porque ela usa apenas um parâmetro:
url.rpartition('.com')[0]
Começando em Python 3.9
, você pode usar removesuffix
:
'abcdc.com'.removesuffix('.com')
# 'abcdc'
Se você precisar remover algum final de uma string, caso exista, não faça nada. Minhas melhores soluções. Você provavelmente desejará usar uma das 2 primeiras implementações, no entanto, incluímos a 3ª por integridade.
Para um sufixo constante:
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'
Para uma regex:
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"
Para uma coleção de sufixos constantes, o caminho assintoticamente mais rápido para um grande número de chamadas:
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')
o final provavelmente é significativamente mais rápido no pypy do que no cpython. A variante regex provavelmente é mais rápida que isso para praticamente todos os casos que não envolvam dicionários enormes de sufixos em potencial que não podem ser facilmente representados como regex pelo menos no cPython.
No PyPy, a variante regex é quase certamente mais lenta para um grande número de chamadas ou seqüências longas, mesmo que o módulo re use um mecanismo regex de compilação do DFA, pois a grande maioria da sobrecarga do lambda será otimizada pelo JIT.
No cPython, no entanto, o fato de o código c em execução para o regex comparar quase certamente as vantagens algorítmicas da versão da coleção de sufixos em quase todos os casos.
import re
def rm_suffix(url = 'abcdc.com', suffix='\.com'):
return(re.sub(suffix+'$', '', url))
Quero repetir esta resposta como a maneira mais expressiva de fazê-lo. Obviamente, o seguinte levaria menos tempo de CPU:
def rm_dotcom(url = 'abcdc.com'):
return(url[:-4] if url.endswith('.com') else url)
No entanto, se a CPU é o gargalo, por que escrever em Python?
Quando a CPU é um gargalo, afinal? Nos motoristas, talvez.
As vantagens do uso de expressão regular são a reutilização do código. E se você quiser remover o '.me', que possui apenas três caracteres?
O mesmo código faria o truque:
>>> rm_sub('abcdc.me','.me')
'abcdc'
No meu caso, eu precisava criar uma exceção, então fiz:
class UnableToStripEnd(Exception):
"""A Exception type to indicate that the suffix cannot be removed from the text."""
@staticmethod
def get_exception(text, suffix):
return UnableToStripEnd("Could not find suffix ({0}) on text: {1}."
.format(suffix, text))
def strip_end(text, suffix):
"""Removes the end of a string. Otherwise fails."""
if not text.endswith(suffix):
raise UnableToStripEnd.get_exception(text, suffix)
return text[:len(text)-len(suffix)]
Aqui, eu tenho um código mais simples.
url=url.split(".")[0]
Supondo que você deseja remover o domínio, não importa o que seja (.com, .net, etc). Eu recomendo encontrar .
e remover tudo a partir desse ponto.
url = 'abcdc.com'
dot_index = url.rfind('.')
url = url[:dot_index]
Aqui estou usando rfind
para resolver o problema de URLs como o abcdc.com.net
que deve ser reduzido ao nome abcdc.com
.
Se você também estiver preocupado com www.
s, verifique-os explicitamente:
if url.startswith("www."):
url = url.replace("www.","", 1)
O 1 em substituir é para edgecases estranhos como www.net.www.com
Se o seu URL ficar mais selvagem do que o visual, as respostas com regex com as quais as pessoas responderam.
Eu usei a função rstrip embutida para fazer o seguinte:
string = "test.com"
suffix = ".com"
newstring = string.rstrip(suffix)
print(newstring)
test
"test.ccom"
.
Este é um uso perfeito para expressões regulares:
>>> import re
>>> re.match(r"(.*)\.com", "hello.com").group(1)
'hello'
Python> = 3.9:
'abcdc.com'.removesuffix('.com')
Python <3.9:
def remove_suffix(text, suffix):
if text.endswith(suffix):
text = text[:-len(suffix)]
return text
remove_suffix('abcdc.com', '.com')