💬 4.3 Kiểu chuỗi (str)
📖 Giới thiệu
Chuỗi (string) là kiểu dữ liệu để lưu trữ văn bản trong Python. Từ tên người, địa chỉ email đến nội dung trang web, chuỗi có mặt ở khắp mọi nơi trong lập trình. Hiểu cách làm việc với chuỗi là kỹ năng thiết yếu cho mọi lập trình viên Python.
Mục tiêu bài học:
- Hiểu cách tạo và lưu trữ chuỗi
- Thành thạo các thao tác cơ bản với chuỗi
- Biết cách định dạng và xử lý chuỗi
- Sử dụng chuỗi trong các ứng dụng thực tế
🔧 Cú pháp
Cách tạo chuỗi:
# Nháy đơn
chuoi_1 = 'Hello Python'
# Nháy đôi
chuoi_2 = "Xin chào Python"
# Triple quotes (nhiều dòng)
chuoi_nhieu_dong = """
Đây là chuỗi
có nhiều dòng
"""
# Raw string (không xử lý escape)
duong_dan = r'C:\Users\name\Documents'Thao tác chuỗi cơ bản:
text = "Python Programming"
# Độ dài
len(text) # 18
# Truy cập ký tự
text[0] # 'P'
text[-1] # 'g'
# Cắt chuỗi (slicing)
text[0:6] # 'Python'
text[7:] # 'Programming'
# Kiểm tra
'Python' in text # True🔬 Phân tích & Giải thích chi tiết
1. 📝 Cách tạo chuỗi
Nháy đơn vs nháy đôi:
# Tương đương nhau
ten_1 = 'Python'
ten_2 = "Python"
# Khi cần dùng nháy trong chuỗi
cau_noi = "Tôi học 'Python' mỗi ngày"
cau_noi_2 = 'Anh ấy nói: "Python rất tuyệt!"'
# Hoặc dùng escape character
cau_noi_3 = "Anh ấy nói: \"Python rất tuyệt!\""Triple quotes cho chuỗi nhiều dòng:
# Thơ hoặc văn bản dài
bai_tho = """
Lập trình viên tôi,
Code Python mỗi ngày,
Bug ít đi rồi!
"""
# SQL query
sql = """
SELECT ten, tuoi, lop
FROM hoc_sinh
WHERE diem_tb > 8.0
ORDER BY diem_tb DESC
"""Raw string:
# Thường dùng cho regex và đường dẫn
duong_dan_windows = r'C:\Users\Python\Documents\file.txt'
regex_pattern = r'\d{3}-\d{3}-\d{4}' # Pattern số điện thoại
# So sánh với chuỗi thường
normal_string = 'C:\\Users\\Python\\Documents\\file.txt'
print(duong_dan_windows == normal_string) # True2. 🔍 Truy cập và cắt chuỗi
Indexing (truy cập ký tự):
text = "PYTHON"
# 012345 (index dương)
# -654321 (index âm)
print(text[0]) # 'P' (ký tự đầu)
print(text[5]) # 'N' (ký tự cuối)
print(text[-1]) # 'N' (ký tự cuối, cách khác)
print(text[-6]) # 'P' (ký tự đầu, cách khác)Slicing (cắt chuỗi):
text = "Python Programming"
# 0123456789...
# Cú pháp: [start:stop:step]
print(text[0:6]) # 'Python'
print(text[7:]) # 'Programming'
print(text[:6]) # 'Python'
print(text[::2]) # 'Pto rgamn' (cách 2 ký tự)
print(text[::-1]) # 'gnimmargorP nohtyP' (đảo ngược)3. 🔧 Các phương thức chuỗi quan trọng
Tìm kiếm và kiểm tra:
text = "Python Programming Language"
# Tìm kiếm
text.find('Python') # 0 (vị trí đầu tiên)
text.find('Java') # -1 (không tìm thấy)
text.count('g') # 3 (số lần xuất hiện)
# Kiểm tra
'Python' in text # True
text.startswith('Python') # True
text.endswith('Language') # TrueThay đổi case:
text = "Python Programming"
text.upper() # 'PYTHON PROGRAMMING'
text.lower() # 'python programming'
text.title() # 'Python Programming'
text.capitalize() # 'Python programming'
text.swapcase() # 'pYTHON pROGRAMMING'Xóa khoảng trắng:
text = " Python Programming "
text.strip() # 'Python Programming'
text.lstrip() # 'Python Programming '
text.rstrip() # ' Python Programming'Tách và nối chuỗi:
# Tách chuỗi
cau = "Python,Java,C++,JavaScript"
ngon_ngu = cau.split(',') # ['Python', 'Java', 'C++', 'JavaScript']
ho_ten = "Nguyễn Văn An"
ho_ten.split() # ['Nguyễn', 'Văn', 'An']
# Nối chuỗi
danh_sach = ['Python', 'Java', 'C++']
ket_qua = ', '.join(danh_sach) # 'Python, Java, C++'4. 🎨 Định dạng chuỗi
F-string (khuyến nghị):
ten = "Minh"
tuoi = 25
diem = 8.75
# F-string
thong_tin = f"Tên: {ten}, Tuổi: {tuoi}, Điểm: {diem:.1f}"
print(thong_tin) # Tên: Minh, Tuổi: 25, Điểm: 8.8Method .format():
# Với index
template = "Tên: {0}, Tuổi: {1}, Điểm: {2:.1f}"
ket_qua = template.format(ten, tuoi, diem)
# Với tên
template = "Tên: {ten}, Tuổi: {tuoi}, Điểm: {diem:.1f}"
ket_qua = template.format(ten=ten, tuoi=tuoi, diem=diem)💻 Ví dụ minh họa
Ví dụ 1: Xử lý thông tin sinh viên
# xu_ly_thong_tin_sinh_vien.py
print("👨🎓 XỬ LÝ THÔNG TIN SINH VIÊN")
print("=" * 40)
# Nhập thông tin
ho_ten_day_du = input("📝 Nhập họ tên đầy đủ: ")
email = input("📧 Nhập email: ")
so_dien_thoai = input("📱 Nhập số điện thoại: ")
# Xử lý họ tên
ho_ten_chuan = ho_ten_day_du.strip().title()
cac_tu = ho_ten_chuan.split()
if len(cac_tu) >= 2:
ho = cac_tu[0]
ten = cac_tu[-1]
ten_dem = ' '.join(cac_tu[1:-1]) if len(cac_tu) > 2 else ""
else:
ho = ho_ten_chuan
ten = ""
ten_dem = ""
# Xử lý email
email_sach = email.strip().lower()
ten_miền = email_sach.split('@')[-1] if '@' in email_sach else ""
# Xử lý số điện thoại
sdt_sach = ''.join(filter(str.isdigit, so_dien_thoai))
# Tạo mã sinh viên từ tên
ma_sv = ""
for tu in cac_tu:
if tu:
ma_sv += tu[0].upper()
ma_sv += sdt_sach[-4:] if len(sdt_sach) >= 4 else "0000"
# Hiển thị kết quả
print(f"\n📋 THÔNG TIN ĐÃ XỬ LÝ:")
print("-" * 30)
print(f"👤 Họ: {ho}")
print(f"👤 Tên đệm: {ten_dem}")
print(f"👤 Tên: {ten}")
print(f"📧 Email: {email_sach}")
print(f"🏢 Tên miền: {ten_miền}")
print(f"📱 SĐT: {sdt_sach}")
print(f"🆔 Mã SV: {ma_sv}")
# Kiểm tra tính hợp lệ
print(f"\n✅ KIỂM TRA:")
print(f"Email hợp lệ: {'@' in email_sach and '.' in ten_miền}")
print(f"SĐT hợp lệ: {len(sdt_sach) >= 10}")
print(f"Họ tên hợp lệ: {len(ho_ten_chuan.split()) >= 2}")Ví dụ 2: Trình soạn thảo văn bản mini
# trinh_soan_thao_mini.py
print("📝 TRÌNH SOẠN THẢO VĂN BẢN MINI")
print("=" * 40)
def phan_tich_van_ban(text):
"""Phân tích thống kê văn bản"""
# Thống kê cơ bản
so_ky_tu = len(text)
so_ky_tu_khong_khoang_trang = len(text.replace(' ', ''))
so_tu = len(text.split())
so_dong = text.count('\n') + 1 if text else 0
# Tìm từ dài nhất
cac_tu = text.split()
tu_dai_nhat = max(cac_tu, key=len) if cac_tu else ""
# Đếm nguyên âm
nguyen_am = "aeiouáàảãạăắằẳẵặâấầẩẫậéèẻẽẹêếềểễệíìỉĩịóòỏõọôốồổỗộơớờởỡợúùủũụưứừửữựýỳỷỹỵ"
so_nguyen_am = sum(1 for char in text.lower() if char in nguyen_am)
return {
'so_ky_tu': so_ky_tu,
'so_ky_tu_khong_khoang_trang': so_ky_tu_khong_khoang_trang,
'so_tu': so_tu,
'so_dong': so_dong,
'tu_dai_nhat': tu_dai_nhat,
'so_nguyen_am': so_nguyen_am
}
def hien_thi_menu():
"""Hiển thị menu tùy chọn"""
print("\n🛠️ MENU:")
print("1. ➕ Nhập văn bản")
print("2. 📊 Phân tích văn bản")
print("3. 🔍 Tìm và thay thế")
print("4. 🔠 Chuyển đổi case")
print("5. 📄 Hiển thị văn bản")
print("0. 🚪 Thoát")
van_ban = ""
while True:
hien_thi_menu()
lua_chon = input("\n👉 Chọn chức năng: ")
if lua_chon == "1":
print("\n📝 Nhập văn bản (nhập 'END' trên dòng mới để kết thúc):")
lines = []
while True:
line = input()
if line == "END":
break
lines.append(line)
van_ban = '\n'.join(lines)
print("✅ Đã lưu văn bản!")
elif lua_chon == "2":
if not van_ban:
print("❌ Chưa có văn bản để phân tích!")
continue
stats = phan_tich_van_ban(van_ban)
print(f"\n📊 THỐNG KÊ VĂN BẢN:")
print("-" * 25)
print(f"📏 Số ký tự: {stats['so_ky_tu']:,}")
print(f"🔤 Ký tự (không khoảng trắng): {stats['so_ky_tu_khong_khoang_trang']:,}")
print(f"📝 Số từ: {stats['so_tu']:,}")
print(f"📄 Số dòng: {stats['so_dong']:,}")
print(f"📏 Từ dài nhất: '{stats['tu_dai_nhat']}'")
print(f"🔤 Số nguyên âm: {stats['so_nguyen_am']:,}")
if stats['so_tu'] > 0:
tb_ky_tu_moi_tu = stats['so_ky_tu_khong_khoang_trang'] / stats['so_tu']
print(f"📊 TB ký tự/từ: {tb_ky_tu_moi_tu:.1f}")
elif lua_chon == "3":
if not van_ban:
print("❌ Chưa có văn bản!")
continue
tu_tim = input("🔍 Nhập từ cần tìm: ")
tu_thay = input("🔄 Nhập từ thay thế: ")
so_lan = van_ban.count(tu_tim)
if so_lan > 0:
van_ban = van_ban.replace(tu_tim, tu_thay)
print(f"✅ Đã thay thế {so_lan} lần!")
else:
print("❌ Không tìm thấy từ cần thay thế!")
elif lua_chon == "4":
if not van_ban:
print("❌ Chưa có văn bản!")
continue
print("\n🔠 Chọn kiểu chuyển đổi:")
print("1. VIẾT HOA")
print("2. viết thường")
print("3. Viết Hoa Đầu Từ")
print("4. Viết hoa đầu câu")
kieu = input("Chọn: ")
if kieu == "1":
van_ban = van_ban.upper()
elif kieu == "2":
van_ban = van_ban.lower()
elif kieu == "3":
van_ban = van_ban.title()
elif kieu == "4":
van_ban = van_ban.capitalize()
else:
print("❌ Lựa chọn không hợp lệ!")
continue
print("✅ Đã chuyển đổi!")
elif lua_chon == "5":
if not van_ban:
print("❌ Chưa có văn bản!")
else:
print(f"\n📄 VĂN BẢN HIỆN TẠI:")
print("-" * 30)
print(van_ban)
print("-" * 30)
elif lua_chon == "0":
print("👋 Tạm biệt!")
break
else:
print("❌ Lựa chọn không hợp lệ!")Ví dụ 3: Validator dữ liệu
# validator_du_lieu.py
import re
def kiem_tra_email(email):
"""Kiểm tra tính hợp lệ của email"""
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
return re.match(pattern, email) is not None
def kiem_tra_so_dien_thoai(sdt):
"""Kiểm tra số điện thoại Việt Nam"""
# Loại bỏ khoảng trắng và ký tự đặc biệt
sdt_sach = re.sub(r'[^\d+]', '', sdt)
# Pattern cho số VN
patterns = [
r'^(\+84|84|0)(3|5|7|8|9)\d{8}$', # Mobile
r'^(\+84|84|0)(2[0-9])\d{8}$' # Landline
]
return any(re.match(pattern, sdt_sach) for pattern in patterns)
def kiem_tra_mat_khau(password):
"""Kiểm tra độ mạnh mật khẩu"""
if len(password) < 8:
return False, "Mật khẩu phải có ít nhất 8 ký tự"
if not re.search(r'[A-Z]', password):
return False, "Mật khẩu phải có ít nhất 1 chữ hoa"
if not re.search(r'[a-z]', password):
return False, "Mật khẩu phải có ít nhất 1 chữ thường"
if not re.search(r'\d', password):
return False, "Mật khẩu phải có ít nhất 1 số"
if not re.search(r'[!@#$%^&*(),.?":{}|<>]', password):
return False, "Mật khẩu phải có ít nhất 1 ký tự đặc biệt"
return True, "Mật khẩu mạnh"
def format_ten_nguoi(ten):
"""Chuẩn hóa tên người"""
# Loại bỏ khoảng trắng thừa
ten = ' '.join(ten.split())
# Viết hoa chữ cái đầu mỗi từ
ten = ten.title()
# Xử lý các trường hợp đặc biệt
replacements = {
' Van ': ' Văn ',
' Thi ': ' Thị ',
' Duc ': ' Đức ',
' Anh ': ' Anh ',
}
for old, new in replacements.items():
ten = ten.replace(old, new)
return ten
# Test validator
print("🔍 VALIDATOR DỮ LIỆU")
print("=" * 30)
while True:
print("\n📝 Chọn loại kiểm tra:")
print("1. 📧 Email")
print("2. 📱 Số điện thoại")
print("3. 🔒 Mật khẩu")
print("4. 👤 Tên người")
print("0. 🚪 Thoát")
lua_chon = input("\nChọn: ")
if lua_chon == "1":
email = input("Nhập email: ")
if kiem_tra_email(email):
print("✅ Email hợp lệ!")
else:
print("❌ Email không hợp lệ!")
elif lua_chon == "2":
sdt = input("Nhập số điện thoại: ")
if kiem_tra_so_dien_thoai(sdt):
print("✅ Số điện thoại hợp lệ!")
else:
print("❌ Số điện thoại không hợp lệ!")
elif lua_chon == "3":
password = input("Nhập mật khẩu: ")
hop_le, thong_bao = kiem_tra_mat_khau(password)
if hop_le:
print(f"✅ {thong_bao}")
else:
print(f"❌ {thong_bao}")
elif lua_chon == "4":
ten = input("Nhập tên: ")
ten_chuan = format_ten_nguoi(ten)
print(f"📝 Tên chuẩn: {ten_chuan}")
elif lua_chon == "0":
print("👋 Tạm biệt!")
break
else:
print("❌ Lựa chọn không hợp lệ!")🏋️ Thực hành
Bài tập 1: Phân tích URL
Nhiệm vụ: Tách các thành phần của URL
# TODO: Nhập URL và tách thành:
# - Protocol (http, https)
# - Domain
# - Path
# - Query parametersĐáp án:
# phan_tich_url.py
def phan_tich_url(url):
"""Phân tích URL thành các thành phần"""
# Tách protocol
if '://' in url:
protocol, phan_con = url.split('://', 1)
else:
protocol = 'unknown'
phan_con = url
# Tách query string
if '?' in phan_con:
phan_con, query = phan_con.split('?', 1)
else:
query = ''
# Tách domain và path
if '/' in phan_con:
domain, path = phan_con.split('/', 1)
path = '/' + path
else:
domain = phan_con
path = '/'
return {
'protocol': protocol,
'domain': domain,
'path': path,
'query': query,
'full_url': url
}
# Test
url = input("Nhập URL: ")
result = phan_tich_url(url)
print("\n📊 PHÂN TÍCH URL:")
for key, value in result.items():
print(f"{key}: {value}")Bài tập 2: Mã hóa Caesar
Nhiệm vụ: Implement thuật toán mã hóa Caesar
# TODO: Mã hóa và giải mã Caesar cipher
# - Dịch chuyển ký tự theo một số bước
# - Xử lý cả chữ hoa và chữ thường
# - Giữ nguyên ký tự đặc biệtĐáp án:
# caesar_cipher.py
def ma_hoa_caesar(text, shift):
"""Mã hóa Caesar với số bước dịch chuyển"""
result = ""
for char in text:
if char.isalpha():
# Xác định base (A hoặc a)
base = ord('A') if char.isupper() else ord('a')
# Dịch chuyển và wrap around
shifted = (ord(char) - base + shift) % 26
result += chr(base + shifted)
else:
# Giữ nguyên ký tự không phải chữ cái
result += char
return result
def giai_ma_caesar(text, shift):
"""Giải mã Caesar"""
return ma_hoa_caesar(text, -shift)
# Test
text = input("Nhập văn bản: ")
shift = int(input("Nhập số bước dịch: "))
ma_hoa = ma_hoa_caesar(text, shift)
giai_ma = giai_ma_caesar(ma_hoa, shift)
print(f"Văn bản gốc: {text}")
print(f"Mã hóa: {ma_hoa}")
print(f"Giải mã: {giai_ma}")Bài tập 3: Text formatter
Nhiệm vụ: Tool định dạng văn bản đa chức năng
# TODO: Tạo tool format văn bản:
# - Căn lề (trái, phải, giữa)
# - Wrap text theo độ rộng
# - Thêm border
# - Số hóa dòngĐáp án:
# text_formatter.py
def can_trai(text, width):
"""Căn trái văn bản"""
lines = text.split('\n')
return '\n'.join(line.ljust(width) for line in lines)
def can_phai(text, width):
"""Căn phải văn bản"""
lines = text.split('\n')
return '\n'.join(line.rjust(width) for line in lines)
def can_giua(text, width):
"""Căn giữa văn bản"""
lines = text.split('\n')
return '\n'.join(line.center(width) for line in lines)
def them_border(text, char='*'):
"""Thêm border xung quanh văn bản"""
lines = text.split('\n')
max_length = max(len(line) for line in lines)
border_line = char * (max_length + 4)
result = [border_line]
for line in lines:
result.append(f"{char} {line.ljust(max_length)} {char}")
result.append(border_line)
return '\n'.join(result)
def so_hoa_dong(text):
"""Thêm số dòng"""
lines = text.split('\n')
max_digits = len(str(len(lines)))
result = []
for i, line in enumerate(lines, 1):
line_num = str(i).rjust(max_digits)
result.append(f"{line_num}| {line}")
return '\n'.join(result)
# Menu chính
text = input("Nhập văn bản cần format: ")
while True:
print("\n🎨 TEXT FORMATTER")
print("1. Căn trái")
print("2. Căn phải")
print("3. Căn giữa")
print("4. Thêm border")
print("5. Số hóa dòng")
print("6. Hiển thị văn bản")
print("0. Thoát")
choice = input("Chọn: ")
if choice == "1":
width = int(input("Độ rộng: "))
text = can_trai(text, width)
print("✅ Đã căn trái!")
elif choice == "2":
width = int(input("Độ rộng: "))
text = can_phai(text, width)
print("✅ Đã căn phải!")
elif choice == "3":
width = int(input("Độ rộng: "))
text = can_giua(text, width)
print("✅ Đã căn giữa!")
elif choice == "4":
char = input("Ký tự border (mặc định *): ") or "*"
text = them_border(text, char)
print("✅ Đã thêm border!")
elif choice == "5":
text = so_hoa_dong(text)
print("✅ Đã số hóa dòng!")
elif choice == "6":
print("\n📄 VĂN BẢN:")
print("-" * 30)
print(text)
print("-" * 30)
elif choice == "0":
break
else:
print("❌ Lựa chọn không hợp lệ!")📋 Tóm tắt
Cách tạo chuỗi:
| Cách | Cú pháp | Sử dụng khi |
|---|---|---|
| Nháy đơn | 'text' | Chuỗi đơn giản |
| Nháy đôi | "text" | Có nháy đơn bên trong |
| Triple quotes | """text""" | Nhiều dòng |
| Raw string | r'text' | Đường dẫn, regex |
Thao tác chuỗi quan trọng:
# Truy cập
text[0] # Ký tự đầu
text[-1] # Ký tự cuối
text[1:5] # Cắt từ vị trí 1 đến 4
# Tìm kiếm
'sub' in text # Kiểm tra có chứa
text.find('sub') # Vị trí đầu tiên
text.count('x') # Đếm số lần xuất hiện
# Thay đổi
text.upper() # Viết hoa
text.lower() # Viết thường
text.strip() # Xóa khoảng trắng
text.replace('old', 'new') # Thay thếĐịnh dạng chuỗi:
# F-string (khuyến nghị)
f"Hello {name}, you are {age} years old"
# .format()
"Hello {}, you are {} years old".format(name, age)
# % formatting (cũ)
"Hello %s, you are %d years old" % (name, age)Patterns thường dùng:
# Kiểm tra và xử lý input
user_input = input("Nhập: ").strip().lower()
# Tách và xử lý
parts = data.split(',')
cleaned = [part.strip() for part in parts]
# Tạo slug từ tiêu đề
slug = title.lower().replace(' ', '-')
# Kiểm tra định dạng
if text.startswith('http'):
# Xử lý URLBest practices:
- 🎯 Sử dụng f-string cho định dạng
- 🧹 Luôn .strip() input từ người dùng
- 🔍 Dùng .lower() khi so sánh không phân biệt hoa thường
- 📝 Raw string cho regex và đường dẫn
- ✂️ Slicing thay vì vòng lặp khi có thể
Chuẩn bị cho bài tiếp theo:
Bài tiếp theo sẽ học về ✅ Kiểu logic (bool) - cách làm việc với True/False và logic trong Python!
💡 Mẹo: Chuỗi trong Python là immutable (không thay đổi được). Mọi thao tác đều tạo ra chuỗi mới!
🔤 Thực hành: Thử tạo một chương trình xử lý tên file để hiểu rõ sức mạnh của string methods!