Cơ bản

Chuỗi trong Python: split, replace, strip, join, cắt lát và f-string

Cập nhật: · Skillaria.Top

Chuỗi trong Python (kiểu str) là dãy ký tự Unicode không thay đổi được. split() tách chuỗi thành danh sách, join() ghép danh sách lại, replace() thay thế đoạn con, strip() bỏ khoảng trắng hai đầu; mỗi phương thức trả về một chuỗi mới. Để chèn giá trị, tiện nhất là dùng f-string: f"{name}: {price:.2f}".

Chuỗi xuất hiện trong mọi chương trình Python: dữ liệu người dùng nhập, tên tệp, các dòng CSV, phản hồi từ API. Kiểu str lưu văn bản theo Unicode, nên tiếng Việt và emoji hoạt động mà không cần cấu hình gì thêm. Các phương thức được dùng nhiều nhất là split, replace, strip và join, còn để hiển thị giá trị thì f-string tiện nhất. Dưới đây là phần giải thích kèm ví dụ.

Chuỗi trong Python hoạt động thế nào

Chuỗi được viết trong dấu nháy đơn hoặc nháy kép — không có khác biệt: 'cà phê' và "cà phê" giống nhau. Ba dấu nháy tạo chuỗi nhiều dòng, trong đó các ký tự xuống dòng được giữ nguyên.

name = "Cà phê"
note = """Dòng đầu tiên
Dòng thứ hai"""
print(len(name))  # 4 — độ dài chuỗi tính theo ký tự

Tính chất quan trọng nhất của chuỗi là không thể thay đổi. Phương thức không sửa chuỗi mà trả về một chuỗi mới. Vì vậy s.replace("a", "b") nếu không gán lại sẽ không có tác dụng — phải viết s = s.replace("a", "b"). Đây là lỗi phổ biến nhất của người mới.

Ký tự đặc biệt, xuống dòng và chuỗi thô

Ký tự xuống dòng được viết là \n, tab là \t, dấu gạch chéo ngược là \\. Tiền tố r tạo chuỗi «thô»: dấu gạch chéo ngược trong đó không được xử lý. Điều này tiện cho đường dẫn Windows và biểu thức chính quy.

print("Tổng cộng:\n350 ₫")
path = r"C:\new\bang.csv"   # \n và \t sẽ không bị biến thành ký tự đặc biệt

Một biểu thức dài có thể xuống dòng trong code bằng cách đặt nó trong dấu ngoặc: các chuỗi liền kề trong ngoặc sẽ do Python tự ghép lại.

split: tách chuỗi thành danh sách

Phương thức split() tách chuỗi theo dấu phân cách và trả về một danh sách. Khi không truyền tham số, nó cắt theo mọi ký tự khoảng trắng và bỏ qua các khoảng trắng lặp lại — tiện cho việc phân tích lệnh.

"add  Cà_phê 250".split()        # ['add', 'Cà_phê', '250']
"2026-10-16".split("-")          # ['2026', '10', '16']
"a,b,,c".split(",")              # ['a', 'b', '', 'c']
"key=value=x".split("=", 1)      # ['key', 'value=x']

Lưu ý sự khác biệt: khi có dấu phân cách rõ ràng, các đoạn rỗng được giữ lại. Tham số thứ hai maxsplit giới hạn số lần cắt, còn rsplit() cắt từ bên phải. Để tách văn bản thành các dòng, dùng splitlines(): nó nhận biết cả \n lẫn \r\n và không tạo phần tử rỗng ở cuối.

text = "cà phê\ntaxi\n"
text.split("\n")     # ['cà phê', 'taxi', '']
text.splitlines()    # ['cà phê', 'taxi']

join: ghép danh sách thành chuỗi

join() là thao tác ngược lại. Phương thức được gọi trên chuỗi phân cách, còn đối số là danh sách các chuỗi:

items = ["cà phê", "taxi", "cơm trưa"]
print(", ".join(items))   # cà phê, taxi, cơm trưa
print("\n".join(items))   # mỗi mục một dòng

Mọi phần tử phải là chuỗi, nếu không sẽ gặp TypeError: sequence item 0: expected str instance, int found. Với số, hãy chuyển đổi trước: ", ".join(str(x) for x in amounts).

Nối và ghép chuỗi

Có thể cộng hai chuỗi bằng +, lặp lại bằng *: "-" * 20. Nhưng nối hàng trăm đoạn trong vòng lặp bằng += sẽ chậm, vì mỗi lần đều tạo một chuỗi mới. Hãy gom các phần vào danh sách rồi ghép bằng một lần join(). Không thể cộng trực tiếp chuỗi với số: "Tổng: " + 5 sẽ gây TypeError, cần dùng str() hoặc f-string.

replace: thay thế đoạn con

replace(old, new) thay tất cả các lần xuất hiện của đoạn con. Tham số thứ ba giới hạn số lần thay.

price = "1 250,50"
price = price.replace(" ", "").replace(",", ".")
print(float(price))                  # 1250.5

"a-b-c".replace("-", "+", 1)         # 'a+b-c'

Phương thức phân biệt chữ hoa, chữ thường và chỉ tìm khớp chính xác. Để thay theo mẫu (ví dụ «mọi chữ số») cần module re và hàm re.sub().

strip, lstrip, rstrip: cắt bỏ khoảng trắng

strip() bỏ khoảng trắng, tab và ký tự xuống dòng ở cả hai đầu. lstrip() chỉ làm sạch bên trái, rstrip() chỉ bên phải. Đây là việc đầu tiên nên làm với dữ liệu người dùng nhập và các dòng đọc từ tệp.

raw = "  Cà phê \n"
raw.strip()       # 'Cà phê'
raw.rstrip()      # '  Cà phê'
"xxCà phêxx".strip("x")   # 'Cà phê'

Tham số là một tập ký tự chứ không phải chuỗi con: "abcVănabc".strip("abc") sẽ bỏ mọi chữ a, b, c ở hai đầu theo bất kỳ thứ tự nào. Để cắt đúng tiền tố hoặc hậu tố, dùng removeprefix() và removesuffix() (từ Python 3.9).

Các phương thức hữu ích khác của chuỗi

Phương thứcTác dụngVí dụ → kết quả
lower(), upper()đổi chữ hoa/thường"Cà phê".lower() → 'cà phê'
startswith(), endswith()kiểm tra đầu và cuối"a.csv".endswith(".csv") → True
find()vị trí đoạn con hoặc -1"cà phê".find("p") → 3
count()số lần xuất hiện"banana".count("a") → 3
isdigit()chỉ có chữ số?"250".isdigit() → True
zfill()thêm số 0 vào đầu"7".zfill(3) → '007'

Để kiểm tra chuỗi có chứa một đoạn hay không, cách đơn giản nhất là toán tử in: if "cà phê" in text.lower():. Các chuỗi được so sánh bằng == từng ký tự và có phân biệt hoa thường; để so sánh không phân biệt hoa thường, đưa cả hai về dạng casefold().

Cắt lát chuỗi

Chuỗi là một dãy, nên có thể truy cập ký tự theo chỉ số bắt đầu từ 0, còn chỉ số âm đếm từ cuối. Phép cắt s[start:stop:step] trả về một đoạn con; cận phải không được bao gồm.

s = "Python"
s[0]      # 'P'
s[-1]     # 'n'
s[0:3]    # 'Pyt'
s[2:]     # 'thon'
s[::2]    # 'Pto'
s[::-1]   # 'nohtyP' — đảo ngược chuỗi

Phép cắt không bao giờ gây lỗi khi vượt biên: s[0:100] trả về toàn bộ chuỗi. Nhưng s[100] sẽ gây IndexError. Không thể đổi một ký tự theo chỉ số (s[0] = "J" — TypeError), phải tạo chuỗi mới: "J" + s[1:].

f-string trong Python

Chữ f đặt trước chuỗi có nghĩa là các biểu thức trong dấu ngoặc nhọn sẽ được tính toán và chèn vào văn bản. Đây là cách định dạng chuỗi chủ đạo từ Python 3.6: ngắn hơn format() và nhanh hơn toán tử % cũ.

item = "Cà phê"
price = 250
print(f"{item}: {price} ₫")              # Cà phê: 250 ₫
print(f"Sau giảm giá: {price * 0.9} ₫")  # Sau giảm giá: 225.0 ₫
print(f"{item=}")                         # item='Cà phê' — tiện khi gỡ lỗi

Định dạng số và căn lề

Sau dấu hai chấm bên trong ngoặc nhọn là đặc tả định dạng. Nó quy định số chữ số thập phân, dấu phân cách hàng nghìn, độ rộng và căn lề:

Cách viếtKết quảÝ nghĩa
f"{3.14159:.2f}"3.14làm tròn đến 2 chữ số
f"{1250000:,}"1,250,000dấu phân cách hàng nghìn
f"{1250000:_}"1_250_000gạch dưới thay cho dấu phẩy
f"{0.256:.1%}"25.6%phần trăm
f"{'cà phê':<10}|"cà phê |căn trái, độ rộng 10
f"{250:>8}" 250căn phải
f"{7:03d}"007thêm số 0 vào đầu

Căn lề rất tiện cho bảng hiển thị trên terminal: f"{name:<12}{amount:>10.2f}" sẽ căn các cột thẳng hàng. Lưu ý rằng định dạng chỉ cần khi hiển thị. Tiền nên lưu bằng số nguyên (đơn vị nhỏ nhất) hoặc Decimal, không dùng float: 0.1 + 0.2 cho ra 0.30000000000000004.

Dấu nháy và xuống dòng bên trong f-string

Từ Python 3.12 (PEP 701), f-string có cú pháp hình thức đầy đủ: bên trong ngoặc nhọn có thể dùng cùng loại dấu nháy với bên ngoài, dấu gạch chéo ngược và xuống dòng, còn độ lồng nhau không còn bị giới hạn. Lỗi bên trong ngoặc giờ chỉ ra đúng vị trí. Trên các phiên bản cũ, hãy dùng loại dấu nháy khác bên trong: f"{d['key']}", còn xuống dòng thì qua một biến trung gian hoặc chr(10).

Với văn bản nhiều dòng, phù hợp là f-string trong ba dấu nháy: f"""Tổng: {total}\nSố mục: {count}""".

format() và %: các cách cũ

Trong code cũ bạn sẽ gặp "{}: {}".format(item, price) và "%s: %d" % (item, price). Đặc tả của format() giống hệt f-string. Phương thức format() vẫn hữu ích khi mẫu được lưu tách khỏi dữ liệu, ví dụ trong file cấu hình.

Phân tích chuỗi: ví dụ thực tế

Hãy kết hợp các phương thức lại. Giả sử từ một tệp đọc được các dòng dạng " 2026-10-16; Cà phê ; 250,50 \n", và cần lấy ngày, tên và số tiền tính bằng đơn vị nhỏ nhất. Trình tự thông thường: làm sạch hai đầu, cắt theo dấu phân cách, làm sạch từng phần, rồi chuyển kiểu.

line = "  2026-10-16; Cà phê ; 250,50 \n"

date, item, raw_amount = [p.strip() for p in line.strip().split(";")]
amount_kop = round(float(raw_amount.replace(",", ".")) * 100)

print(date, item, amount_kop)            # 2026-10-16 Cà phê 25050
print(f"{item:<10}{amount_kop / 100:>10.2f}")

Nếu số phần không phải ba, phép giải nén sẽ lỗi với ValueError: not enough values to unpack hoặc too many values to unpack. Trong code thật, nên kiểm tra các dòng như vậy trước hoặc bắt ngoại lệ. Với các tệp CSV thực sự có dấu nháy và ký tự thoát, nên dùng module chuẩn csv thay vì split.

Lỗi thường gặp với chuỗi

  • Không lưu kết quả của phương thức: s.strip() không gán lại thì không thay đổi gì.
  • join trên danh sách số — TypeError; hãy dùng map(str, ...) trước.
  • strip với chuỗi con: đối số là tập ký tự; để bỏ tiền tố cần removeprefix().
  • So sánh phân biệt hoa thường: "Cà phê" == "cà phê" — False.
  • Đường dẫn Windows không có tiền tố r sẽ bị biến dấu gạch chéo ngược thành ký tự đặc biệt.

t-string: mẫu thay vì văn bản có sẵn

Python 3.14 bổ sung t-string. Trông chúng giống f-string, chỉ khác tiền tố t, nhưng kết quả khác: không phải một chuỗi đã hoàn chỉnh mà là đối tượng string.templatelib.Template. Trong đó, các đoạn văn bản (.strings) và các giá trị được chèn vào (.values) được lưu riêng.

name = "<script>"
tpl = t"Xin chào, {name}!"
print(tpl.strings)   # ('Xin chào, ', '!')
print(tpl.values)    # ('<script>',)

Vì sao điều này hữu ích: thư viện nhận được các giá trị trước khi ghép và có thể xử lý chúng — ví dụ thoát ký tự < trong HTML hoặc truyền tham số an toàn vào truy vấn SQL. f-string không cho cơ hội đó, vì nó đã ghép tất cả. Để in ra thông thường, vẫn dùng f-string.

Tổng kết

Để làm việc hằng ngày với chuỗi trong Python chỉ cần một bộ công cụ nhỏ: split() và join() tách và ghép văn bản, strip() làm sạch đầu vào, replace() thay thế đoạn, phép cắt lát lấy đoạn con, còn f-string hiển thị giá trị với định dạng mong muốn. Hãy nhớ tính không thay đổi của chuỗi: phương thức trả về chuỗi mới, và bạn phải lưu lại kết quả đó. Chuỗi, số và f-string được thực hành trên ví dụ trình theo dõi chi tiêu trong bài giảng về Python của khóa học.

Câu hỏi thường gặp

Làm sao biết độ dài của một chuỗi trong Python?

Hàm len(s) trả về số ký tự. Với tiếng Việt và emoji, đếm theo ký tự Unicode chứ không theo byte; số byte cho bởi len(s.encode("utf-8")).

Làm sao đổi số thành chuỗi và ngược lại?

str(250) cho '250', còn int("250") và float("2.5") là chiều ngược lại. Nếu chuỗi không phải số, int() sẽ gây ValueError, nên cần kiểm tra dữ liệu đầu vào.

Vì sao replace không đổi chuỗi của tôi?

Chuỗi không thay đổi được, replace trả về chuỗi mới. Hãy gán kết quả: s = s.replace("a", "b").

Làm sao kiểm tra chuỗi có rỗng không?

Chuỗi rỗng được coi là sai, nên chỉ cần if not s:. Nếu chuỗi có thể chỉ chứa khoảng trắng, hãy kiểm tra if not s.strip():.

t-string khác f-string ở điểm nào?

f-string trả về ngay một str đã hoàn chỉnh, còn t-string (Python 3.14 trở lên) là đối tượng Template với các đoạn văn bản và giá trị tách riêng. Nhờ vậy có thể thoát dữ liệu an toàn cho HTML và SQL.

Học chủ đề này qua video

Chủ đề này được giảng chi tiết kèm thực hành trong khóa học “Python 3.15: от новичка до профи”.

Đến khóa học