Python实现冒犯词星号替换时如何避免丢失文本原有换行符
问题原因
原代码的换行丢失问题来自str.split()的默认行为:无参数调用split()时,会将所有连续的空白字符(包含普通空格、换行符\n、制表符\t等)统一识别为分隔符,切分得到的词列表完全丢失了原文本中空白的类型和位置信息,最后用单个空格' '拼接所有词,自然会把所有换行、多空格都替换为单空格,破坏原排版。
修复方案
提供两种可直接使用的修改版本,均保留原代码「大小写不敏感、整词匹配替换」的核心逻辑:
最小改动版
仅新增逐行处理逻辑,不改变原代码行内的处理规则,适合不想引入额外模块的场景:
def replace_words(text, exclude_list): processed_lines = [] # 先按换行切分,逐行处理保证换行符不丢失 for line in text.split('\n'): words = line.split() for i in range(len(words)): if words[i].lower() in exclude_list: words[i] = "*" processed_lines.append(' '.join(words)) # 用换行符拼接回完整文本 return '\n'.join(processed_lines)
注:该版本和原代码逻辑一致,行内连续的多个空格会被合并为单个空格,如果需要完整保留所有空白格式,使用下面的正则版本。
全格式保留版
通过正则匹配所有非空白的词单元,全程不修改任何空白字符,可100%保留原文本的换行、缩进、连续空格等格式,同时长文本处理效率更高:
import re def replace_words(text, exclude_list): # 提前将敏感词转为小写集合,提升匹配效率 exclude_set = {word.lower() for word in exclude_list} def replace_match(match): word = match.group(0) return "*" if word.lower() in exclude_set else word # 仅匹配连续非空白字符做替换,所有空白字符原样保留 return re.sub(r'\S+', replace_match, text)
可选调整
如果需要替换后的星号长度和原敏感词长度一致,把两个版本中赋值"*"的代码修改为"*" * len(words[i])(最小改动版)或"*" * len(word)(正则版)即可。
内容的提问来源于stack exchange,提问作者Jason Howard
相关产品推荐
相关产品推荐

