Tôi có đoạn mã sau:
url = 'abcdc.com'
print(url.strip('.com'))
Tôi mong đợi: abcdc
Tôi đã nhận: abcd
Bây giờ tôi làm
url.rsplit('.com', 1)
Có cách nào tốt hơn?
Tôi có đoạn mã sau:
url = 'abcdc.com'
print(url.strip('.com'))
Tôi mong đợi: abcdc
Tôi đã nhận: abcd
Bây giờ tôi làm
url.rsplit('.com', 1)
Có cách nào tốt hơn?
Câu trả lời:
strip
không có nghĩa là "loại bỏ chuỗi con này". x.strip(y)
coi y
như một tập hợp các ký tự và loại bỏ bất kỳ ký tự nào trong tập hợp đó từ cuối của x
.
Thay vào đó, bạn có thể sử dụng endswith
và cắt:
url = 'abcdc.com'
if url.endswith('.com'):
url = url[:-4]
Hoặc sử dụng các biểu thức thông thường :
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
tên miền không phân biệt chữ hoa chữ thường. (Đây là phiếu bầu cho giải pháp regex)
rsplit()
giải pháp không có hành vi tương tự như endswith()
khi chuỗi ban đầu không có chuỗi con ở cuối, nhưng ở đâu đó ở giữa. Ví dụ: "www.comeandsee.com".rsplit(".com",1)[0] == "www.comeandsee"
nhưng"www.comeandsee.net".rsplit(".com",1)[0] == "www"
s[:-n]
có một cảnh báo: vì n = 0
, điều này không trả về chuỗi có các ký tự 0 cuối cùng bị cắt, nhưng thay vào đó là chuỗi trống.
Nếu bạn chắc chắn rằng chuỗi chỉ xuất hiện ở cuối, thì cách đơn giản nhất sẽ là sử dụng 'thay thế':
url = 'abcdc.com'
print(url.replace('.com',''))
www.computerhope.com
. làm một kiểm tra với endswith()
và sẽ ổn.
def strip_end(text, suffix):
if not text.endswith(suffix):
return text
return text[:len(text)-len(suffix)]
return text[:-len(suffix)]
Vì có vẻ như chưa có ai chỉ ra điều này:
url = "www.example.com"
new_url = url[:url.rfind(".")]
Điều này sẽ hiệu quả hơn các phương thức sử dụng split()
vì không có đối tượng danh sách mới nào được tạo và giải pháp này hoạt động cho các chuỗi có nhiều dấu chấm.
Phụ thuộc vào những gì bạn biết về url của mình và chính xác những gì bạn đang cố gắng làm. Nếu bạn biết rằng nó sẽ luôn kết thúc bằng '.com' (hoặc '.net' hoặc '.org') thì
url=url[:-4]
là giải pháp nhanh nhất. Nếu đó là một URL tổng quát hơn thì có lẽ bạn nên xem xét thư viện urlparse đi kèm với python.
Mặt khác, nếu bạn muốn xóa mọi thứ sau trận chung kết '.' trong một chuỗi
url.rsplit('.',1)[0]
sẽ làm việc. Hoặc nếu bạn muốn chỉ muốn mọi thứ lên đến đầu tiên '.' vậy hãy thử đi
url.split('.',1)[0]
Trong một dòng:
text if not text.endswith(suffix) or len(suffix) == 0 else text[:-len(suffix)]
Thế còn url[:-4]
?
.ca
hoặc một .co.uk
url.
Đối với các url (vì nó dường như là một phần của chủ đề theo ví dụ đã cho), người ta có thể làm một cái gì đó như thế này:
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)
Cả hai sẽ xuất ra:
('http://www.stackoverflow', '.com')
Điều này cũng có thể được kết hợp với str.endswith(suffix)
nếu bạn chỉ cần tách ".com" hoặc bất cứ điều gì cụ thể.
url.rsplit ('. com', 1)
không hoàn toàn đúng
Những gì bạn thực sự cần phải viết là
url.rsplit('.com', 1)[0]
và nó trông khá ngắn gọn IMHO.
Tuy nhiên, sở thích cá nhân của tôi là tùy chọn này vì nó chỉ sử dụng một tham số:
url.rpartition('.com')[0]
Bắt đầu từ Python 3.9
, bạn có thể sử dụng removesuffix
thay thế:
'abcdc.com'.removesuffix('.com')
# 'abcdc'
Nếu bạn cần tước một số đầu của chuỗi nếu nó tồn tại thì không làm gì cả. Giải pháp tốt nhất của tôi. Bạn có thể sẽ muốn sử dụng một trong 2 triển khai đầu tiên tuy nhiên tôi đã bao gồm lần thứ 3 để hoàn thiện.
Đối với một hậu tố không đổi:
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'
Đối với một 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"
Đối với một tập hợp các hậu tố không đổi, cách nhanh nhất không có triệu chứng cho một số lượng lớn các cuộc gọi:
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')
cái cuối cùng có lẽ nhanh hơn đáng kể trong pypy sau đó là cpython. Biến thể regex có khả năng nhanh hơn phiên bản này đối với hầu hết các trường hợp không liên quan đến từ điển lớn của các hậu tố tiềm năng không thể được biểu diễn dễ dàng như một regex ít nhất là trong cPython.
Trong PyPy, biến thể regex gần như chắc chắn chậm hơn đối với số lượng lớn cuộc gọi hoặc chuỗi dài ngay cả khi mô-đun re sử dụng công cụ regex biên dịch DFA vì phần lớn chi phí của lambda sẽ được JIT tối ưu hóa.
Tuy nhiên, trong cPython, thực tế là mã c đang chạy của bạn cho regex gần như chắc chắn sẽ vượt qua các ưu điểm thuật toán của phiên bản bộ sưu tập hậu tố trong hầu hết các trường hợp.
Nếu bạn có nghĩa là chỉ tước phần mở rộng:
'.'.join('abcdc.com'.split('.')[:-1])
# 'abcdc'
Nó hoạt động với bất kỳ phần mở rộng nào, với các dấu chấm tiềm năng khác hiện có trong tên tệp. Nó chỉ đơn giản là tách chuỗi dưới dạng một danh sách trên các dấu chấm và nối nó mà không có phần tử cuối cùng.
import re
def rm_suffix(url = 'abcdc.com', suffix='\.com'):
return(re.sub(suffix+'$', '', url))
Tôi muốn lặp lại câu trả lời này là cách diễn đạt nhất để làm điều đó. Tất nhiên, những điều sau đây sẽ tốn ít thời gian CPU hơn:
def rm_dotcom(url = 'abcdc.com'):
return(url[:-4] if url.endswith('.com') else url)
Tuy nhiên, nếu CPU là cổ chai tại sao lại viết bằng Python?
Khi nào CPU là cổ chai? Trong trình điều khiển, có thể.
Ưu điểm của việc sử dụng biểu thức chính quy là khả năng sử dụng lại mã. Điều gì xảy ra nếu tiếp theo bạn muốn xóa '.me', chỉ có ba ký tự?
Cùng một mã sẽ thực hiện các mẹo:
>>> rm_sub('abcdc.me','.me')
'abcdc'
Trong trường hợp của tôi, tôi cần phải đưa ra một ngoại lệ vì vậy tôi đã làm:
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)]
Ở đây, tôi có một mã đơn giản nhất.
url=url.split(".")[0]
Giả sử bạn muốn xóa tên miền, bất kể đó là gì (.com, .net, v.v.). Tôi khuyên bạn nên tìm .
và loại bỏ mọi thứ từ thời điểm đó.
url = 'abcdc.com'
dot_index = url.rfind('.')
url = url[:dot_index]
Ở đây tôi đang sử dụng rfind
để giải quyết vấn đề của các url abcdc.com.net
nên được giảm tên abcdc.com
.
Nếu bạn cũng quan tâm đến www.
s, bạn nên kiểm tra chúng một cách rõ ràng:
if url.startswith("www."):
url = url.replace("www.","", 1)
1 trong thay thế là dành cho edgecase lạ như www.net.www.com
Nếu url của bạn trở nên hoang dã hơn, hãy nhìn vào câu trả lời regex mà mọi người đã phản hồi.
Tôi đã sử dụng hàm rstrip tích hợp để thực hiện như sau:
string = "test.com"
suffix = ".com"
newstring = string.rstrip(suffix)
print(newstring)
test
"test.ccom"
.
Đây là một cách sử dụng hoàn hảo cho các biểu thức thông thường:
>>> import re
>>> re.match(r"(.*)\.com", "hello.com").group(1)
'hello'
Con trăn> = 3.9:
'abcdc.com'.removesuffix('.com')
Con trăn <3.9:
def remove_suffix(text, suffix):
if text.endswith(suffix):
text = text[:-len(suffix)]
return text
remove_suffix('abcdc.com', '.com')