如何用Python和正则表达式提取文本结构化信息?
许多人在日常工作中不得不处理大量的文本。
比如学者需要阅读大量的文献资料,寻找灵感、数据和论据。
学生需要阅读许多教科书和论文,然后自己写报告或制作幻灯片。
财务分析师需要从大量的新闻报道中找到行业发展趋势和目标企业动态的线索。
不是所有的文字处理都这么新鲜有趣。
一项重要但繁琐的任务是从大量文本中提取结构化信息。
许多数据分析场景需要输入结构化信息。
比如“贷款与否:如何利用Python和机器学习帮助你决策?”?以及“如何利用Python和深度神经网络锁定即将流失的客户?如您所见,机器模型更喜欢结构化的表格信息。
但是,结构化的信息不一定就在那里,等着你去用。很多时候,它隐藏在过去生成的非结构化文本中。
你可能习惯于手动阅读文本信息,提取关键点,然后复制粘贴到表格中。原则上,这是可以理解的。但实际操作起来,效率太低,太麻烦。
大多数人都不愿意从事这种简单重复的枯燥工作。
反复重复鼠标划定文本范围,“Ctrl+C”,切换到表格文档,准确找到输入位置,然后“CTRL+V”...
这种事情做多了,可能会对你的肩肘关节,甚至身心健康产生不良影响。
要不要尝试用一种更简单的自动化方法来快速的替你完成这些烦人的操作步骤??
看完这篇文章,希望你能找到答案。
样品
这里,我们给出一个极其简化的中文文本信息抽取的例子。
这样做的原因是为了避免在解释数据上花费太多时间。
希望你能把重点放在方法上,掌握新的知识。
假设一个高中班主任让班长统计学生高考后的毕业去向。班长做了认真的调查,然后做了如下汇报:
张华被北京大学录取了。
李萍进入了中等技术学校。
韩梅梅走进了百货商店。
……
为了让你熟悉例子,甚至还有* * *音。在这里,我“借用”了1998新华字典的一些内容。
那不是很甜蜜吗?
现实生活中,一个班很可能不止三个人,所以你可以想象这是一长串句子。
但实际上,班主任还有一个没有表达出来的隐含意思,即:
我要一张表格!
所以,看到这一长串句子,可以想象他的表情。
班长估计也很尴尬:
如果你想要表格,你应该说的!
这时,假设你是班长,你该怎么办?
信息都在正文里。但是如果需要转换成表格,就要一个一个的找,一个一个的处理。
其实对于一个四五十人的班级来说,手工操作并不是太难。
但是试想一下,如果你需要处理的数据量是这个例子的十倍、百倍甚至千万倍呢?
继续坚持手工处理?
这不仅麻烦,而且不现实。
我们需要找到一种简单的方法来帮助我们自动提取相应的信息。
我们在这里使用的方法是一个正则表达式。
规则的
“正则表达式”这个名字乍听起来很神秘。其实就是从英文“正则表达式”翻译过来的。
如果翻译成白话,就是“正则表达式形式”。
这个,听起来,是不是更接地气?
不过,给你补上“打假专家101”这门课:
说别人听得懂的话能唬谁?
按照惯例,还是继续用“正则表达式”来称呼吧。
自问世以来,它给文本处理带来了高效率。
但是,使用它的主要人群不是经常和文字打交道的作家、编辑、学者、文员,而是...
节目编排者
程序员写的代码是文本;程序员处理的许多数据也是文本格式的。有许多显著的规律可循。
正是有了正则表达式的独特秘密,很多别人需要在黑暗中一整周的任务,程序员半个小时就能完成,喝完咖啡再等工作。
即使在泛人工智能的今天,正则表达式仍然有很多意想不到的应用。
例如人机对话系统。
你可能看过新闻报道,一直认为人机对话是知识图谱或者深度学习做出来的。
不能说没有以上酷派科技的参与。但他们充其量只占其中的一部分,也许只是很小的一部分。
在生产实践中,大量对话规则的背后,并不是一个神秘高深的神经网络,而是一堆正则表达式。
你可能会担心,你自己能掌握这么高端的应用技术吗?
答案是:
当然可以!
正则表达式不难学。
尤其是你把它和Python结合起来,简直就是效率神器。
让我们看看正则表达式如何帮助我们识别样本文本中的“姓名”和“去向”信息。
审判实践
请打开浏览器并键入此URL (/)。
您将看到以下界面。
它可以成为正则表达式实验的利器。我教INFO 5731的时候,同学们在掌握了这个工具之后,很快就玩起了正则表达式。
这么好的工具一定很贵吧?
不,它是免费的。可以大胆使用。
我们先把左边的编程语言从默认的PHP调整为Python。
之后,将要处理的文本粘贴到中间空白的大文本框中。
我们试着搭配一下。
什么是匹配?
就是你写一个表达式,计算机会以一地鸡毛为箭,在每一行文字上,认真寻找是否有符合表达式的文字段落。
如果有,会突出显示。
我们在这里观察一下,发现每一句话里,人的前面都有一个“了”字。
好了,我们就在中间上方的小文本框里输入“了”字吧。
大家可以看到,三个句子里的“了”都亮了。
这是你接触到的第一种匹配方法——根据字符的本义找到一致的内容。
由于样文的规律性,我们可以把“了”看作是一个定位器,在它之后,到句尾,就是“去”的信息。
这不就是我们要找的那一半结构化信息吗?
我们试着匹配“to”。
怎么搭配?这次每一行的字都不一样吧?
没关系,正则表达式的威力在这个时候就展现出来了。
可以用点,也就是,。,来表示任何字符。
字母、数字、标点符号...甚至中文也可以覆盖。
那我们继续想吧。这里会有多少字?
我不知道。
在这简单的三句话中,有“四个字”或“六个字”两种情况。
因此,我们不能在目的地信息中指定字符的长度。
不过没关系,我们只需要一个星号(*)来代表出现的次数,从?0到无穷大可以匹配。
当然,在实践中,无穷大不会真的出现。
我们补充道。*到刚才的输入,结果看起来是这样的:
还不错!
但是目的地信息和“了”字好像是用同一个颜色高亮显示的。那不是搞混了吗?
我们不想这样。
我们做什么呢
请你去好吗?尝试在的两边添加一对括号(注意不要使用中文全角符号)。
你会发现“了”这次还是蓝色的,而后面的目的地信息变成了绿色。
这对括号非常重要。称为“分组”,是提取信息的基本单位。
我们已经完成任务一半了,不是吗?
让我们试着把名字一起提取出来。
我们来找一下名字的锚位。
仔细观察,你很容易发现每个名字后面都有一个动词。
进入高等学校的学生用“考”字,就业的学生用“进”。
我们先来试试“考”这个词。
这里我们尽量把“考”字直接放在“了”字前面。但是你会发现没有匹配。
为什么?
回头看资料,会发现别人用的原词是“录取”。
当然,我们可以在这里输入“上”字。但是你要考虑更一般的情况。
比如考上了怎么办?“录取”呢?
比较好的方法是继续使用我们刚刚学过的“大招”,在“考”和“了”之间插入一个. *。
这个时候你的正则表达式是什么样子的?我通过了考试。* (.*)
你看,第一行的信息匹配成功了吗?
但是,还是有两条线不匹配。我该怎么办?
如果我们遵循同样的模式,我们会发现它被用于。* (.*)?您可以正确匹配最后两行。
问题来了:
匹配第一行的不能匹配最后两行,反之亦然。
这可不好。我们希望写出更通用的表达方式。
我们做什么呢
让我们看看正则表达式中“或”关系的表示。
这里我们可以用一条竖线将两个字符分开,并用括号括起来,表示其中任何一个出现,匹配成功。
也就是把正则表达式写成:[Kao | Jin]。*乐(。*).
太好了,三条线都匹配成功了。
这里使用动词短语和时态“了”作为中间锚点信息,因此我们可以安全而大胆地提取以前的名称信息。
也就是说是这样写的:(。*)【考过|】。*是(。*).
注意,此时,名称分组是绿色的,目的分组是红色的。
我们成功提取了两组信息!庆祝一下!
但是,如果你把这里的成绩给班主任看,估计他也不会满意。
表格!我要表格!
别急,轮到Python了。
让我们试着用Python正式提取数据。
环境
这篇文章的配套源代码,我放在Github上了。
可以在我的微信官方账号“nkwangshuyi”后台回复“regex”查看完整代码链接。
如果你对我的教程满意,请点击页面右上角的星星,帮我加一颗星。谢谢你
请注意,在这个页面的中央,有一个按钮,上面写着“在Colab中打开”。请点击它。
然后,Google Colab会自动打开。
建议你点击上图中用红色圈出的“复制到驱动器”按钮。这样就可以保存在自己的Google Drive中,方便使用和查看。
Colab为你提供了一个完整的运行环境。你只需要依次执行代码,就可以重现本教程的运行结果。
如果你不熟悉Google Colab,没关系。我这里有一个教程,专门讲解Google Colab的特点和用法。
为了让你更深入的学习和理解代码,我建议你在Google Colab中打开一个全新的笔记本,输入代码,按照以下运行。在这个过程中,充分理解代码的含义。
这种看似笨拙的方式,其实是一种有效的学习方式。
密码
首先,阅读Python正则表达式包。
进口re
然后,我们准备好数据。注意,为了演示代码的通用性,我在这里的末尾添加了一行文本,与之前的文本规则不同,看看我们的代码能否正确处理。
Data = " "张华考上了北大。
李萍进入了中等技术学校。
韩梅梅走进了百货商店。
他们都有美好的未来。
然后,是时候写正则表达式了。真的需要自己手写吗?
当然不是。
强大的regex101网站帮助我们做好了准备。
请点击上图中用红色圈出的按钮,网站会为您准备一个初始代码的模板,可以匹配您需要的图案。
不需要完全复制代码。有这么一句话,很重要。直接复制粘贴到Colab笔记本就可以了。
Regex = r”(。*)【入考|】。*没了(。*) "
这就是你的正则表达式在Python中的样子。
我们准备一个空列表来接收数据。
我的列表= []
然后,写一个循环。
对于data.split中的行(' n '):
?mysearch = re.search(regex,line)
?如果我搜索:
name = mysearch.group(1)
dest = mysearch.group(2)
mylist.append((name,dest))
让我给你解释一下这个循环中每个句子的意思:
data.split('n ')?将文本数据拆分成行。所以我们可以得到每一行的数据。mysearch = re.search(regex,line)?这个句子试图把模式和线匹配起来。如果我搜索?这个判断语句是为了让程序区分这条线是否有我们要找的图案。例如,在最后一行文本中,没有我们前面分析的文本模式。遇到这样的台词,直接跳过。name = mysearch.group(1)?是不是说第一组匹配的内容,也就是regex101网站中绿色代表的名字是分组存储的?名字?在变量中。下一句等等。注意?团体?根据括号在正则表达式中出现的顺序,从1开始计数。mylist.append((name,dest))?将从这一行提取的信息存储在我们之前定义的空列表中。
注意,不加的话?mysearch = re.search(regex,line)?在这句话里,程序会尝试匹配每一行,提取分组内容,然后结果会是这样的错误:
所以你看,用正则表达式提取信息的时候,不能粗暴。
与此同时,我们可以看一看吗?我的列表?该列表的内容:
我的列表
结果如下:
[('张华','北大'),('李萍','中专'),('韩梅梅','百货大楼')]
有,一个不多,一个不少,正是我们需要的。
我们将把它导出到一个表格中。方法有很多,但最简单的是使用Pandas数据分析软件包。
进口熊猫作为pd
就用它?警察。DataFrame?函数,我们可以把一个由上面的链表和元组组成的二维结构变成一个数据帧。
df = pd。数据框架(我的列表)
Df.columns = ['name ',' destination']
请注意,我们在这里也非常仔细地修改了标题。
看看你的劳动成果:
df
对于数据框,只需一行代码就可以将其转换为Excel格式:
df.to_excel("dest.xlsx ",index=False)
进入文件选项卡,刷新并检查当前目录的内容:
这个?dest.xlsx?是输出的结果。下载后,我们可以用Excel打开。
任务完成!
你可以把成绩提交给班主任,看到他满意的笑容。
总结
在本教程中,我们讨论了如何利用文本字符法则和Python以及正则表达式来提取结构化信息。
我希望你已经掌握了以下技巧:
了解正则表达式的作用;
尝试正则表达式匹配regex101网站并生成初步代码;
使用Python批量提取信息,根据需求将结构化数据导出为指定格式。
还是那句话,这么简单的例子,用上面的方法绝对是蚊子的大轰炸。
但是,如果你需要处理的数据量很大,这种方法节省的时间会很可观。
希望你能举一反三,在自己的工作中灵活运用。
更多Python知识请关注:Python自学网!!