Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Python

Python - Thay thế từ trùng lặp trong chuỗi

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ại i.
  • 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ề word nế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