文本清洗之前,先问清楚换行能不能丢

举报
yd_228020411 发表于 2026/10/30 15:45:20 2026/10/30
【摘要】 把连续空白统一为空格,能让搜索更方便,也可能让比较程序漏掉段落变化。用一个可运行的小例子,区分原始文本、结构表示和搜索表示。

处理文本时,常见的一行代码是:

def normalize(text):
    return " ".join(text.split())

它把词拆开,再用一个空格拼起来。连续空格、换行和制表符造成的形式差异,都会被压平。做关键词搜索时,这通常很方便;拿它判断两份文档是否一样,就需要先明确比较范围。

看两个固定示例:

old = "Alpha\nBeta"
new = "Alpha Beta"

print(old == new)
print(normalize(old) == normalize(new))
print(old.splitlines())
print(new.splitlines())

输出是:

False
True
['Alpha', 'Beta']
['Alpha Beta']

原始字符串不相同,归一化结果却相同。比较函数没有算错,而是输入转换已经抹掉了换行信息。下游再精确地比较字符串,也无法从两个相同的结果中还原这次变化。

这里最先要做的决定,是换行在业务里代表什么。

全文搜索可以主要关心词是否出现。配置文件、代码和分行说明可能还关心行边界。文档比较则可能需要区分段落、列表项和文本框。不能只因为它们最后都能表示成字符串,就使用同一种清洗规则。

一个直接的做法是保留不同用途的表示:

def representations(text):
    return {
        "raw": text,
        "lines": text.splitlines(),
        "search": " ".join(text.split()),
    }

a = representations(old)
b = representations(new)
print(a["raw"] != b["raw"])
print(a["lines"] != b["lines"])
print(a["search"] == b["search"])

这三个结果可以同时为真:原文有变化,行结构有变化,搜索表示没有变化。它们回答的是不同问题。

splitlines() 只是这个示例的演示工具,不能直接当成所有文档的段落解析器。它默认不保留行结束符,单纯比较它的结果,也无法覆盖每一种原文差异。处理 PPTX、HTML 等结构化格式时,应从格式本身读取段落、节点或文本框,再决定哪些边界参与比较。

验证清洗规则时,至少准备三组输入:完全相同的文本、仅改变分行的文本、真正修改一个词的文本。分别写清楚预期结果。这样能检查程序有没有把应该保留的差异提前清掉,也能发现检测逻辑是不是始终返回“相同”。

清洗规则可以简化数据,但简化掉的信息也应当是明确允许丢弃的信息。先确定用途,再选择表示,比事后追查一次漏报更容易。

参考:Python 官方文档,str.split、str.join、str.splitlines

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。