Việc dùng .find() hoặc .index() để kiểm tra xem một đoạn văn bản có tồn tại trong chuỗi là điều thường gặp—và rồi bạn có thể gặp hành vi lạ như ValueError hoặc bỏ sót kết quả khớp ở đầu chuỗi. Nhạy cảm chữ hoa/thường, ranh giới cắt lát lệch 1 đơn vị, và việc str không có phương thức .contains() càng khiến mọi thứ rối rắm. Cách khắc phục rất đơn giản: dùng đúng công cụ cho đúng việc. Ta dựa vào toán tử in để kiểm tra tồn tại, .find()/.index() để lấy vị trí, .count() để đếm, và .replace() để thay thế—kèm vài kỹ thuật an toàn với Unicode khi cần bỏ qua phân biệt hoa/thường.
Python xử lý tìm kiếm chuỗi con như thế nào
Chuỗi văn bản của Python là Unicode. Các thao tác với chuỗi con mặc định phân biệt hoa/thường và được hiện thực bằng C để đạt tốc độ. Cách trực tiếp nhất để kiểm tra xem văn bản xuất hiện trong chuỗi là dùng toán tử in, trả về Boolean dựa trên hiện thực __contains__() của chuỗi. Khi bạn cần vị trí hoặc số đếm, hãy dùng các phương thức str chuyên dụng. Tham số tùy chọn start và end tuân theo ngữ nghĩa cắt lát: start bao gồm; end loại trừ.
Kiểm tra chứa với in
Dùng "needle" in haystack khi bạn chỉ cần biết chuỗi con có tồn tại hay không. Cách này dễ đọc và tránh phải xử lý chỉ số.
text ="Banana bread"print("ban"in text)# False (case-sensitive)print("Ban"in text)# TrueĐược hỗ trợ bởi
Để kiểm tra không phân biệt hoa/thường, hãy chuẩn hóa cả hai phía. .casefold() nhận thức Unicode tốt hơn .lower() và là lựa chọn mặc định của tôi cho đối sánh không phân biệt hoa/thường.
pattern ="ban"print(pattern.casefold()in text.casefold())# TrueĐược hỗ trợ bởi
Khi nên dùng: kiểm tra tồn tại nhanh, xác thực đầu vào, lọc danh sách.
Trường hợp biên: "" in s luôn True (chuỗi rỗng nằm trong mọi chuỗi).
Phương thức str.find()
Cú pháp
str.find() trả về chỉ số thấp nhất của chuỗi con, hoặc -1 nếu không tìm thấy. start và end tùy chọn để giới hạn phạm vi tìm kiếm.
Phương thức này không thay đổi tại chỗ; nó trả về một bản sao.
message ="The red house is between the blue house and the old house"print(message.replace("house","car"))# The red car is between the blue car and the old carprint(message.replace("house","car",2))# The red car is between the blue car and the old houseĐược hỗ trợ bởi
Thay thế không phân biệt hoa/thường
Để thay thế không phân biệt hoa/thường đồng thời giữ nguyên hoa/thường gốc, hãy dùng re.sub() với re.IGNORECASE, hoặc chuẩn hóa với .casefold() nếu bạn không cần giữ nguyên kiểu chữ ban đầu.
Đối sánh không phân biệt hoa/thường với .casefold()
.casefold() cung cấp chuẩn hóa chữ hoa/thường mạnh và nhận thức Unicode, được ưu tiên hơn .lower() cho kiểm tra không phân biệt hoa/thường.
query ="straße"# German 'straße'
text ="STRASSE und mehr"# Uppercase variantprint(query.casefold()in text.casefold())# TrueĐược hỗ trợ bởi
Công cụ liên quan cho tiền tố và hậu tố
Với phần đầu/cuối đã biết, hãy dùng các phương thức chuyên dụng—chúng nhanh và rõ ràng hơn so với cắt lát hoặc regex:
s.startswith(prefix) và s.endswith(suffix) (chấp nhận tuple cho nhiều lựa chọn)
s.removeprefix(prefix) và s.removesuffix(suffix) (Python 3.9+)
filename ="draft_report_v2.pdf"print(filename.removeprefix("draft_"))# report_v2.pdfprint(filename.endswith((".pdf",".docx")))# TrueĐược hỗ trợ bởi
Làm việc với cột Pandas
Khi tìm kiếm trên nhiều chuỗi trong một cột DataFrame, hãy dùng các phương thức chuỗi vector hóa. Đặt regex=False để khớp theo ký tự literal.
End là loại trừ, vì vậy vị trí tìm kiếm phản chiếu ngữ nghĩa cắt lát.
headline ="Where's Waldo?"print(headline.find("Waldo",0,6))# -1 (searching "Where'")print(headline.find("Waldo",0,13))# 8 (searching up to the 'o' in Waldo)Được hỗ trợ bởi
Bài tập thực hành Tìm kiếm và Thay thế Chuỗi trong Python
Ví dụ này xử lý một danh sách mô tả phim ngắn. Nó minh họa kiểm tra tồn tại, tìm kiếm có giới hạn, và thay thế an toàn không dùng regex.
blurbs =["Critics say the lead actor delivers a career-best performance.","Fans argue the actor actor scene was intentionally repetitive.","A clever cameo steals the show."]for blurb in blurbs:# Check whether "actor" appears between indexes 20 and 40 (end exclusive).
window_has_actor ="actor".casefold()in blurb[20:40].casefold()ifnot window_has_actor:print("Window check: actor not found")continue# If "actor actor" appears, collapse to a single "actor".if"actor actor"in blurb:print(blurb.replace("actor actor","actor"))# If "actor actor actor" appears, collapse to a single "actor".elif"actor actor actor"in blurb:print(blurb.replace("actor actor actor","actor"))else:print(blurb)Được hỗ trợ bởi
Đầu ra:
Window check: actor not found
Fans argue the actor scene was intentionally repetitive.
Window check: actor not foundĐược hỗ trợ bởi
Kết luận
Dùng toán tử in cho kiểm tra chứa đơn giản, .find() hoặc .index() khi cần vị trí, .count() để đếm không chồng lấp, và .replace() để thay thế. Chuẩn hóa với .casefold() cho kiểm tra không phân biệt hoa/thường, và ưu tiên các trợ thủ tiền tố/hậu tố chuyên dụng khi phù hợp. Ta tránh chuyển kết quả .find() sang Boolean và coi hành vi với chuỗi rỗng là trường hợp đặc biệt để giữ cho mã xử lý chuỗi đúng đắn và rõ ràng.
Việc dùng
.find()hoặc.index()để kiểm tra xem một đoạn văn bản có tồn tại trong chuỗi là điều thường gặp—và rồi bạn có thể gặp hành vi lạ nhưValueErrorhoặc bỏ sót kết quả khớp ở đầu chuỗi. Nhạy cảm chữ hoa/thường, ranh giới cắt lát lệch 1 đơn vị, và việcstrkhông có phương thức.contains()càng khiến mọi thứ rối rắm. Cách khắc phục rất đơn giản: dùng đúng công cụ cho đúng việc. Ta dựa vào toán tửinđể kiểm tra tồn tại,.find()/.index()để lấy vị trí,.count()để đếm, và.replace()để thay thế—kèm vài kỹ thuật an toàn với Unicode khi cần bỏ qua phân biệt hoa/thường.Python xử lý tìm kiếm chuỗi con như thế nào
Chuỗi văn bản của Python là Unicode. Các thao tác với chuỗi con mặc định phân biệt hoa/thường và được hiện thực bằng C để đạt tốc độ. Cách trực tiếp nhất để kiểm tra xem văn bản xuất hiện trong chuỗi là dùng toán tử
in, trả về Boolean dựa trên hiện thực__contains__()của chuỗi. Khi bạn cần vị trí hoặc số đếm, hãy dùng các phương thứcstrchuyên dụng. Tham số tùy chọnstartvàendtuân theo ngữ nghĩa cắt lát: start bao gồm; end loại trừ.Kiểm tra chứa với in
Dùng
"needle" in haystackkhi bạn chỉ cần biết chuỗi con có tồn tại hay không. Cách này dễ đọc và tránh phải xử lý chỉ số.Để kiểm tra không phân biệt hoa/thường, hãy chuẩn hóa cả hai phía.
.casefold()nhận thức Unicode tốt hơn.lower()và là lựa chọn mặc định của tôi cho đối sánh không phân biệt hoa/thường."" in sluônTrue(chuỗi rỗng nằm trong mọi chuỗi).Phương thức str.find()
Cú pháp
str.find()trả về chỉ số thấp nhất của chuỗi con, hoặc-1nếu không tìm thấy.startvàendtùy chọn để giới hạn phạm vi tìm kiếm.Ví dụ và tình huống sử dụng
Dùng
.find()khi bạn cần vị trí và có thể xử lý giá trị “không tìm thấy” mà không cần ngoại lệ.Đừng viết
if s.find(sub):để kiểm tra tồn tại. Nếu khớp ở chỉ số 0, điều kiện là falsey.Phương thức str.index()
Cú pháp
.index()tương tự.find()nhưng némValueErrorkhi chuỗi con không tồn tại.Ví dụ và khi nào nên chọn
Dùng
.index()khi chuỗi con bắt buộc phải tồn tại và ngoại lệ là cách thất bại phù hợp.Phương thức str.count()
Cú pháp
.count()trả về số lần xuất hiện không chồng lấp. Nó cũng chấp nhận giới hạnstartvàend.Ví dụ và trường hợp biên
Dùng
.count()để đếm nhanh mà không cần regex.Trường hợp đặc biệt: chuỗi rỗng.
Phương thức str.replace()
.replace()trả về một chuỗi mới trong đó các lần xuất hiện củaoldđược thay bằngnew. Dùngcountđể giới hạn số lần thay thế.Thay thế chuỗi con
Phương thức này không thay đổi tại chỗ; nó trả về một bản sao.
Thay thế không phân biệt hoa/thường
Để thay thế không phân biệt hoa/thường đồng thời giữ nguyên hoa/thường gốc, hãy dùng
re.sub()vớire.IGNORECASE, hoặc chuẩn hóa với.casefold()nếu bạn không cần giữ nguyên kiểu chữ ban đầu.Đối sánh không phân biệt hoa/thường với .casefold()
.casefold()cung cấp chuẩn hóa chữ hoa/thường mạnh và nhận thức Unicode, được ưu tiên hơn.lower()cho kiểm tra không phân biệt hoa/thường.Công cụ liên quan cho tiền tố và hậu tố
Với phần đầu/cuối đã biết, hãy dùng các phương thức chuyên dụng—chúng nhanh và rõ ràng hơn so với cắt lát hoặc regex:
s.startswith(prefix)vàs.endswith(suffix)(chấp nhận tuple cho nhiều lựa chọn)s.removeprefix(prefix)vàs.removesuffix(suffix)(Python 3.9+)Làm việc với cột Pandas
Khi tìm kiếm trên nhiều chuỗi trong một cột DataFrame, hãy dùng các phương thức chuỗi vector hóa. Đặt
regex=Falseđể khớp theo ký tự literal.Ghi chú:
regex=True, nên các ký tự đặc biệt như.sẽ khớp với bất kỳ ký tự nào trừ khi bạn tắt regex.na=.... VớiStringDtype, giá trị thiếu mặc định làFalsetrong mặt nạ.Lỗi thường gặp và trường hợp biên
Không có .contains() trên str: dùng
"sub" in s."abc".contains("a")sẽ némAttributeError.Độ truthy của .find(): chỉ số
0là falsey; hãy so sánh với!= -1hoặc ưu tiên dùnginđể kiểm tra tồn tại..index() ném ngoại lệ: xử lý
ValueErrornếu chuỗi con có thể không tồn tại.Chuỗi rỗng:
"" in slàTrue;s.find("")trả về0;s.count("")làlen(s)+1.Phân biệt hoa/thường: mọi thao tác đều phân biệt hoa/thường trừ khi bạn chuẩn hóa hoặc dùng cờ regex.
Bytes so với text: đừng trộn
bytesvàstrtrong tìm kiếm; hãy giải mã hoặc mã hóa để khớp kiểu.Ngữ nghĩa chuỗi con:
"ab" in "cat,bat"làFalsedù"a"và"b"xuất hiện riêng rẽ—kết quả khớp phải liền kề.Ví dụ thực hành bạn có thể chạy
Những đoạn ngắn này minh họa các mẫu đúng và làm nổi bật các lỗi thường gặp.
Kiểm tra tồn tại
Tìm kiếm có giới hạn với start và end
End là loại trừ, vì vậy vị trí tìm kiếm phản chiếu ngữ nghĩa cắt lát.
Đếm và thay thế
Bài tập thực hành Tìm kiếm và Thay thế Chuỗi trong Python
Ví dụ này xử lý một danh sách mô tả phim ngắn. Nó minh họa kiểm tra tồn tại, tìm kiếm có giới hạn, và thay thế an toàn không dùng regex.
Đầu ra:
Kết luận
Dùng toán tử
incho kiểm tra chứa đơn giản,.find()hoặc.index()khi cần vị trí,.count()để đếm không chồng lấp, và.replace()để thay thế. Chuẩn hóa với.casefold()cho kiểm tra không phân biệt hoa/thường, và ưu tiên các trợ thủ tiền tố/hậu tố chuyên dụng khi phù hợp. Ta tránh chuyển kết quả.find()sang Boolean và coi hành vi với chuỗi rỗng là trường hợp đặc biệt để giữ cho mã xử lý chuỗi đúng đắn và rõ ràng.