前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >自动添加标签(1):初次实现

自动添加标签(1):初次实现

作者头像
不可言诉的深渊
发布2019-07-26 16:44:34
1.4K0
发布2019-07-26 16:44:34
举报

今天介绍如何使用Python杰出的文本处理功能,包括使用正则表达式将纯文本文件转换为用HTML和XML等语言标记的文件。如果不熟悉这些语言的人编写了一些文本,而你要在系统中使用并对其内容进行标记,就必需具备这些技能。

你不能熟练的使用XML?不用为此担心,只要对HTML有大致了解就行。如果需要阅读HTML简介,网上的教程数不胜数。

下面先来实现一个只能做基本处理的简单原型,再对这个程序进行扩展,让标记系统更灵活。

1.问题描述

你要给纯文本文件添加格式。假设你要将一个文件做网页,而给你文件的人嫌麻烦,没有以HTML的格式编写它。你不想手工添加需要的所有标签,想编写一个程序来自动完成这项工作。


注意 事实上,这种“纯文本标记”在最近几年已非常普遍,主要原因可能是带纯 文本界面的维基百科和博客软件呈爆炸式增长。


大致而言,你的任务是对各种文本元素(如标题和突出的文本)进行分类,再清晰地标记它们。就这里的问题而言,你将给文本添加HTML标记,得到可作为网页的文档,让Web浏览器能够显示它。然而,创建基本引擎后,完全可以添加其他类型的标记(如各种形式的XML和LATEX编码)。对文本文件进行分析后,你甚至可以执行其他的任务,如提取所有标题以制作目录。


注意 LATEX是一种创建各种技术文档的标记系统,基于TEX排版程序。这里 提到它只是想说明所要创建程序的其他用途。要深入了解LATEX,可访 问TEX用户组网站(http://www.tug.org)。


你拿到的文本可能包含一些线索(突出的文本形如*like this*),但要让程序能够猜出文档的结构,可能需要一些技巧。

着手编写原型前,先来定义一下目标。

  • 输入无需包含人工编码或标签。
  • 程序需要能够处理不同文本块(如标题、段落和列表项)以及内嵌文本(如突出的文本和URL)。
  • 虽然这个实现添加的是HTML标签,但应该很容易对其进行扩展,以支持其他标记语言。在程序的第一个版本中,可能无法实现所有这些目标,但这正式原型的意义所在。你编写原型旨在找出最初的想法存在的缺陷以及学习如何编写程序来解决面临的问题。

提示 在可能的情况下,最好逐渐修改最初的程序,而不要推倒重来。为清晰 起见,我将提供两个完全独立的程序版本。


2.有用的工具

想想编写这个程序需要哪些工具。

  • 肯定需要读写文件,至少要从标准输入(sys.stdin)读取以及使用print进行输出。
  • 可能需要迭代输入行。
  • 需要使用一些字符串方法。
  • 可能用到一两个生成器。
  • 可能需要模块re。
  • 如果你不熟悉上述任何概念,请花点时间复习一下。

3.准备工作

开始编码前,还需要有评估进度的途径,为此需要一个测试套件。就这个项目而言,一个测试就足够了:一个(纯文本)测试文档。下图是你要对其进行自动标记的示例文本。

要对实现进行测试,只需将这个文档作为输入,并在Web浏览器中查看结果(或直接检查标签)即可。


注意 相比于人工检查结果,使用自动化测试套件通常是更佳的选择。


4.初次实现

首先要做的事情之一是将文本分成段落。段落之间有一个或多个空行。比段落更准确的说法是(block),因为块也可以指标题和列表项。

4.1.找出文本块

要找出这些文本块,一种简单的方法是,收集空行前的所有行并将它们返回,然后重复这样的操作。不需要收集空行,因此不需要返回空文本块(即多个空行)。另外,必须保证文件的最后一行为空行,否则无法确定最后一个文本块到哪里结束。(当然,有其他确定这一点的方法)

下图演示了这种方法的一种实现。

生成器lines是个简单的工具,在文件末尾添加一个空行。生成器blocks实现了刚才描述的方法。生成文本块时,将其包含的所有行合并,并将两端的空白(如列表项缩进和换行符)删除,得到一个表示文本块的字符串。(如果不喜欢这种找出段落的方法,你肯定能够设计出其他方法。请看看你最终能设计出多少种方法,这可能很有趣。)我将这些代码存储在文件util.py中,这意味着你稍后可在程序中导入这些生成器。

4.2.添加一些标记

使用这些基本功能,可创建简单的标记脚本。为此,可按如下基本步骤进行。

(1)打印一些起始标记。

(2)对于文本块,在段落标签内打印它。

(3)打印一些结束标记。

这不太难,但用处也不大。这里假设要将第一个文本块放在一级标题标签(h1)内,而不是段落标签内。另外,还需将用星号括起的文本改成突出文本(使用标签em)。这样程序将更有用一些。由于已经编写好了函数blocks,使用re.sub实现这些需求的代码非常简单,如下图所示。

要执行这个程序,并将前面的示例文件作为输入,可像下面这样做:

python simple_markup.py <test_input.txt> test_output.html

这样,文件test_output.html将包含生成的html代码。下图是在Web浏览器中显示这些HTML代码的结果。

这个原型虽然不是很出色,但也确实执行了一些重要的任务。它将文本分成可独立处理的文本块,再依次对每个文本块应用一个过滤器(这个过滤器是通过调用re.sub实现的)。这种方法看起来不错,可在最终的程序中使用。

如果要扩展这个原型,该怎么办呢?可在for循环中添加检查,以确定文本块是否是标题、列表项等。为此,需要添加其他的正则表达式,代码可能很快变得很乱。更重要的是,要让程序输出其他格式的代码(而不是HTML)很难,但这个项目的目标之一就是能够轻松地添加其他输出格式。这里假设你要重构这个程序,以采用稍微不同的结构。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-07-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python机器学习算法说书人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档