Khi cần thay thế các lần xuất hiện trùng lặp của một từ trong chuỗi (giữ lần đầu, thay các lần sau), có thể dùng split(), index(), dictionary và list comprehension.
Ví dụ
text = 'Jane is the best. Jane loves to cook. Jane and Will cook together'
print(f"Chuỗi gốc: {text}")
# Từ cần thay thế: 'Jane' -> 'She' (từ lần 2 trở đi)
replace_dict = {'Jane': 'She'}
words = text.split(' ')
print(f"Tách từ: {words}")
# Logic: nếu từ trong replace_dict VÀ index từ != index xuất hiện đầu tiên -> thay thế
result_words = [
replace_dict.get(word) if word in replace_dict and words.index(word) != i
else word
for i, word in enumerate(words)
]
result = ' '.join(result_words)
print(f"\nKết quả: {result}")
Kết quả
Chuỗi gốc: Jane is the best. Jane loves to cook. Jane and Will cook together Kết quả: Jane is the best. She loves to cook. She and Will cook together
Giải thích
split(' ')tách chuỗi thành list từ (giữ dấu câu dính với từ).words.index(word)trả về index xuất hiện ĐẦU TIÊN của từ.enumerate(words)cho index hiện tạii.- Nếu
i != words.index(word)-> không phải lần đầu -> thay thế. replace_dict.get(word)lấy giá trị thay thế, mặc định trả vềwordnếu không có trong dict.
Vấn đề với cách trên: dấu câu
Từ 'best.' và 'best' được coi khác nhau. Cần xử lý dấu câu:
import re
def replace_duplicates_preserve_punct(text, replacements):
"""
Thay thế từ trùng lặp, giữ nguyên dấu câu.
Args:
text: chuỗi gốc
replacements: dict {từ_gốc: từ_thay_thế}
"""
# Tách từ nhưng giữ dấu phân cách (spaces, punctuation)
# Pattern: word boundaries
tokens = re.findall(r'\b\w+\b|\S', text)
# \b\w+\b: từ (chữ/số/_), \S: ký tự không phải space (dấu câu đơn lẻ)
seen = set()
result = []
for token in tokens:
if token in replacements:
if token in seen:
result.append(replacements[token])
else:
seen.add(token)
result.append(token)
else:
result.append(token)
return ''.join(result)
text = "Jane is the best. Jane loves to cook. Jane and Will cook together."
print(replace_duplicates_preserve_punct(text, {'Jane': 'She'}))
# Jane is the best. She loves to cook. She and Will cook together.
Cách đơn giản hơn: dùng regex substitution
import re
def replace_after_first(text, target, replacement):
"""Thay thế target bằng replacement từ lần 2 trở đi."""
count = 0
def replacer(match):
nonlocal count
count += 1
return match.group(0) if count == 1 else replacement
return re.sub(rf'\b{re.escape(target)}\b', replacer, text)
text = "Jane is the best. Jane loves to cook. Jane and Will cook together."
print(replace_after_first(text, 'Jane', 'She'))
# Jane is the best. She loves to cook. She and Will cook together.
Thay thế nhiều từ cùng lúc
def replace_multiple_duplicates(text, replace_dict):
"""Thay thế nhiều từ trùng lặp cùng lúc."""
# Tách token giữ dấu cách
tokens = re.findall(r'\S+|\s+', text)
seen = {word: 0 for word in replace_dict}
result = []
for token in tokens:
if token in replace_dict:
seen[token] += 1
if seen[token] > 1:
result.append(replace_dict[token])
else:
result.append(token)
else:
result.append(token)
return ''.join(result)
text = "A B A C B A"
print(replace_multiple_duplicates(text, {'A': 'X', 'B': 'Y'}))
# A B X C Y X