Chuyển đến nội dung chính

Tìm kiếm và thay thế chuỗi trong Python: in, .find(), .index(), .count(), và .replace()

Các mẫu thực tế để tìm, đếm và thay thế chuỗi con trong Python hiện đại.
· 8 phút đọc

Khám phá cùng AI

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

Để 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
  • 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.

s.find(substring, start=0, end=len(s))

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ệ.

tagline = "Ship fast. Fix faster."
print(tagline.find("fast"))         # 5
print(tagline.find("fast", 6))      # 16
print(tagline.find("slow"))         # -1

Đừ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.

name = "Alice"
if name.find("A"):         # Wrong: 0 is Falsey
    print("Found A")       # Will not run
if name.find("A") != -1:   # Correct
    print("Found A")

Phương thức str.index()

Cú pháp

.index() tương tự .find() nhưng ném ValueError khi chuỗi con không tồn tại.

s.index(substring, start=0, end=len(s))

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.

product = "USB-C Cable"
print(product.index("Cable"))  # 6

try:
    product.index("HDMI")
except ValueError:
    print("Required label missing")

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ạn start và end.

s.count(substring, start=0, end=len(s))

Ví dụ và trường hợp biên

Dùng .count() để đếm nhanh mà không cần regex.

log_line = "ERROR: timeout. ERROR: retry. ERROR: gave up."
print(log_line.count("ERROR"))     # 3
print(log_line.count("WARN"))      # 0

Trường hợp đặc biệt: chuỗi rỗng.

print("abc".count(""))   # 4 (len(s) + 1)

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ủa old được thay bằng new. Dùng count để giới hạn số lần thay thế.

s.replace(old, new, count=-1)

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.

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 car

print(message.replace("house", "car", 2))
# The red car is between the blue car and the old house

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 variant
print(query.casefold() in text.casefold())  # True

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.pdf
print(filename.endswith((".pdf", ".docx")))  # True

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.

import pandas as pd

cities = pd.Series(["New York", "Yorktown", None, "Toronto"], dtype="string")
mask = cities.str.contains("York", regex=False, na=False)
print(mask.tolist())  # [True, True, False, False]

Ghi chú:

  • Mặc định, 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.
  • Xử lý giá trị null qua na=.... Với StringDtype, giá trị thiếu mặc định là False trong 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ém AttributeError.

  • Độ truthy của .find(): chỉ số 0 là falsey; hãy so sánh với != -1 hoặc ưu tiên dùng in để kiểm tra tồn tại.

  • .index() ném ngoại lệ: xử lý ValueError nếu chuỗi con có thể không tồn tại.

  • Chuỗi rỗng: "" in s là 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 bytes và str trong 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à False dù "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

headline = "Where's Waldo?"
print("Waldo" in headline)          # True
print("Wenda" in headline)          # False
print(headline.find("Waldo"))       # 8
print(headline.find("Wenda"))       # -1

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.

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)

Đếm và thay thế

inventory = "apple, apple, pear, apple"
print(inventory.count("apple"))                # 3
print(inventory.replace("apple", "orange", 2)) # orange, orange, pear, apple

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()
    if not 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)

Đầu ra:

Window check: actor not found
Fans argue the actor scene was intentionally repetitive.
Window check: actor not found

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.

Chủ đề

Liên quan