Python中文文本信息抽取中常见的正则表达式

本文的方法全部添加到工具包 JioNLP一个全面快捷的NLP工具包
可以立即获取各种正则,以及调用接口!!强烈推荐

我在使用python做一些文本信息抽取的时候,用到了python的正则表达式匹配。所以这里对常见的python正则表达式做一个归纳。找干货直接看粗体字

本文使用的是python2.7.13版本解释器。
要点包括:中文的正则匹配,python的编码格式,re包里的一些函数


1. 座机电话号码

网上很多的文本信息给出的座机电话号码其实给出的很不规范,主要是中文和英文括号符号混用的问题,这涉及到了正则匹配中文的情况,用正则表达式去寻找文本中的有效的电话号码有点麻烦。比如以下这一段文本中给出的电话号码(我想我已经列的很全了)。

该通知于发布日起生效,请申请人于2017年8月30日前将材料递交到管理中心。
联系电话:(0355)3849512, (0355)39482753, 010 38492045,010-39481253, 0242—24891023,010——39281234,69384023,400-820-8820
联系人:陈先生,王小姐

在上面的例子中, 中文括号()和英文括号(),中文间隔符—和英文间隔符-,甚至区号和电话号码中间使用了中文破折号,还有的电话号码没有给出区号,一些客服电话,这些情况在相当多的文本当中都是存在的。

其中,像没有区号的电话 69384023,存在意义并不大,所以我不去抽取,当然如果确实需要抽取,那其实也很简单的,代码如下:

>>>import re
>>>tel = re.findall(r'\d{7,8}', text)  # 输出为结果列表

为了解决混杂字符的电话号码抽取问题,我们需要知道python2.7的字符编码,参考python2.7中的字符编码问题。该文中的内容不多解释,举一个例子:

解释器按utf-8格式编码,我在解释器中存入上面的文本,显示得到的结果是:

>>>text
Out[3]: '\xe8\xaf\xa5\xe9\x80\x9a\xe7\x9f\xa5\xe4\xba\x8e\xe5\x8f\x91\xe5\xb8\x83\xe6\x97\xa5\xe8\xb5\xb7\xe7\x94\x9f\xe6\x95\x88\xef\xbc\x8c\xe8\xaf\xb7\xe7\x94\xb3\xe8\xaf\xb7\xe4\xba\xba\xe4\xba\x8e2017\xe5\xb9\xb48\xe6\x9c\x8830\xe6\x97\xa5\xe5\x89\x8d\xe5\xb0\x86\xe6\x9d\x90\xe6\x96\x99\xe9\x80\x92\xe4\xba\xa4\xe5\x88\xb0\xe7\xae\xa1\xe7\x90\x86\xe4\xb8\xad\xe5\xbf\x83 \xe8\x81\x94\xe7\xb3\xbb\xe7\x94\xb5\xe8\xaf\x9d\xef\xbc\x9a\xef\xbc\x880355\xef\xbc\x893849512\xef\xbc\x8c (0355)39482753\xef\xbc\x8c 010-39481253\xef\xbc\x8c 0242\xe2\x80\x9424891023\xef\xbc\x8c010\xe2\x80\x94\xe2\x80\x9439281234\xef\xbc\x8c69384023 \xe8\x81\x94400-820-8820\xe7\xb3\xbb\xe4\xba\xba\xef\xbc\x9a\xe9\x99\x88\xe5\x85\x88\xe7\x94\x9f\xef\xbc\x8c\xe7\x8e\x8b\xe5\xb0\x8f\xe5\xa7\x90'

>>>len(text)
Out[13]: 248

字符串以str类型存入内存,一个汉字使用3个字节表示,\x38\x25\x28表示一个汉字字符。因此该字符串的长度有248。

如果我以unicode格式存入上述文本,也就是在字符串前加u,显示结果为:

>>>text
Out[10]: u'\u8be5\u901a\u77e5\u4e8e\u53d1\u5e03\u65e5\u8d77\u751f\u6548\uff0c\u8bf7\u7533\u8bf7\u4eba\u4e8e2017\u5e748\u670830\u65e5\u524d\u5c06\u6750\u6599\u9012\u4ea4\u5230\u7ba1\u7406\u4e2d\u5fc3 \u8054\u7cfb\u7535\u8bdd\uff1a\uff080355\uff093849512\uff0c (0355)39482753\uff0c 010-39481253\uff0c 0242\u201424891023\uff0c010\u2014\u201439281234\uff0c69384023 \u8054\u7cfb\u4eba400-820-8820\uff1a\u9648\u5148\u751f\uff0c\u738b\u5c0f\u59d0'

>>>len(text)
Out[11]: 136

这里\u9b23表示一个汉字,字符串长度是136,这才是我们想要的字符串的长度,(248-136)/2正是上文中汉字的个数。

需要说明,python在处理字符串的时候,使用print函数打印字符串中的内容,或将抽取到的信息存入数据库中,不论使用哪种编码方式,打印和存入数据库的结果都是中文没有问题。

下面列出电话号码中的几种符号编码,也可以在上面的代码中找得到。

符号utf-8unicode
中文 (\xef\xbc\x88\uff08
中文 )\xef\xbc\x89\uff09
中文 —\xe2\x80\x94\u2014

根据这个可以进行座机电话号码的正则匹配。这篇文章比较全面的介绍了语法Python正则表达式指南
下面直接给出现成代码:

>>>tel = re.findall(r'\xef\xbc\x88?0\d{2,3}\xef\xbc\x89\d{7,8}', text)
>>>print tel

console显示结果为:

(0355)3849512

由于上述座机号码的模式非常多,综合一下,处理如下:
如果采用了utf-8编码的话,匹配模式为(可以直接copy拿去,找出任何奇葩类型的座机电话号码)

>>>tel = re.findall(r'\xef\xbc\x880\d{2,3}\xef\xbc\x89\d{7,8}|\(?0\d{2,3}[) -]?\d{7,8}|0\d{2,3}\xe2\x80\x94\d{7,8}|0\d{2,3}\xe2\x80\x94\xe2\x80\x94\d{7,8}|\d{3,4}[ -]?\d{3,4}[ -]?\d{4}', text)  # 输出结果为列表
>>>print tel
['\xef\xbc\x880355\xef\xbc\x893849512', '(0355)39482753', '010-39481253', '0242\xe2\x80\x9424891023', '010\xe2\x80\x94\xe2\x80\x9439281234']
>>>for i in xrange(len(tel)):
       print tel[i]
(0355)3849512
(0355)39482753
010-39481253
0242—24891023
010——39281234
400-820-8820

在这里必须要强调的是:
1、如果采用了unicode编码的话,正则匹配会失败,原因在于utf-8编码模式下,每一个ASCII码对应一个字节,而unicode编码下,每一个ascii码对应了两个字节,re包只能按照ascii码字符识别pattern中的内容,将这些字符转换成unicode之后,就识别不了了。
re包可以处理unicode 编码格式的匹配模式,比如 text=u"…" 这样,但是必须是先定义好字符串,然后再用将 该 text 字符串放在函数里,即可匹配unicode 格式的中文文本。
2、re包里提供了compile函数和findall函数,另外还有大量的match函数,search函数,split函数,group函数等等。在python解释器上执行这些函数的时候,调用代码对象而不是一个字符串,性能上会有明显提升。所以,如果是在做大量文本匹配的时候,要避免使用findall,而是用compile函数先将模式转换为代码对象,这样能够提高性能。
3、我在使用python的时候,发现Python2中,如果不定义编码格式,中文会有两种处理方式,一种是三个字节长度表示一个汉字,如上所述,另一种是两个字节长度表示一个汉字。这两种编码方式在python中都是被认可的。但是,在做中文正则匹配时,需要区别对待。


2. 手机号码

从大量文本中利用re抽取手机号码比较简单(我没有具体考虑三大运营商开放号码的细节),正则表达式为:

>>>pattern = re.compile(r'1[345789]\d{9}')

但是如果文本里有一个银行账号如下:

请将汇款打入银行账号622204158291273940001,中国工商银行。

那么用上面的式子去匹配该段文本会找出来15829127394,错误的被当成了电话号码。
然后我决定这么匹配:

>>>pattern = re.compile(r'[^\d]1[345789]\d{9}[^\d]')
>>>cell_num = re.findall(pattern, text)  # text即上面的文本
>>>if cell_num:
       for i in xrange(len(cell_num)):
           print cell_num[i][1:len(cell_num[i])-1]

这样就可以剔除银行账号,身份证号里的错误手机号,找到正确的电话号码了


3.电子邮箱

讲真网上很多博客写的那个电子邮箱表达式我看了、试了都觉得写的很是蛋疼,匹配种类少,错误多。有的只匹配163邮箱的,只匹配 .com邮箱,有的人连 \w相当于字母数字下滑杠都不知道就出来写个博客瞎糊弄。
http://blog.csdn.net/catkint/article/details/55260281
http://blog.csdn.net/u012965373/article/details/51395599
http://blog.csdn.net/linwh8/article/details/50614363
http://www.bkjia.com/ASPjc/846889.html
http://www.cjjjs.com/paper/bcyy/2016821144646609.aspx
以上都是不可取的。
邮箱种类很多:

dongdong.123@163.com
学校的邮箱xixi_xixi.xixi@buaa.com.cn
企业的邮箱123beibei.123_beibei@qiye.csn.net

值得参考的是这个博客里的代码,比较全面,可以拿来主义
python邮箱匹配的正确姿势

>>>email_pattern = re.compile(r'([\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+)')

具体用法是:

>>>email = re.findall(email_pattern, text)  # text代表被抽取邮箱信息的文本
>>>outcome = []
>>>if email:
       for i in xrange(email):
           outcome.append(email[i][0])
>>>print outcome  # 得到文本中所有的邮箱并存入列表

4.身份证号码

不多说了,比较单一固定,拿来主义

r = r'^([1-9]\d{5}[12]\d{3}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])\d{3}[0-9xX])$'
ID_num = re.findall(r, text)

5.银行卡号

也是比较固定的位数,格式有好几种:

中国工商银行:622202 1702357908932
中国农业银行:6222 6247 1935 7438 072
中国民生银行:6223-1024-0589-2038-132
中国工商银行:6222021702357908932

没啥难度,当然,银行卡前几位的数字也和手机号一样,很有规律,但是因为银行卡号位数比较固定,所以就不考虑那么多情况了。拿来主义一下:

r = r'\d{4}[- ]?\d{4}[- ]?\d{4}[- ]?\d{4}[- ]?\d{3}|\d{6}[ -]\d{13}'
account_num = re.findall(r, text)
  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
中文名: 正则表达式经典实例 原名: Regular Expression Cookbook 作者: (美)高瓦特斯(Goyvaerts,J.) (美)利维森(Levithan,S.)译者: 郭耀 资源格式: PDF 版本: 扫描版 出版社: 人民邮电出版社书号: 9787115228321发行时间: 2010年06月01日 地区: 大陆 语言: 简体中文 简介: 编辑推荐 每个程序员都会遇到需要使用正则表达式的情况,但是要用好正则表达式却并不容易。本书提供了100多个实例,以帮助读者使用正则表达式处理数据和文本。即使有经验的用户也经常会遇到性能不佳、误报、漏报等让人挠头的错误,本书对于如何使用正则表达式来解决一些常见的问题给出了按部就班的解决方案,其包括c#、Java、JavaScript、Perl、PHP、Python、Ruby和VB.NET的实例。   本书主要包括以下内容:   通过一个精练的教程理解正则表达式的基本原理和技巧;   在不同的编程语言和脚本语言有效使用正则表达式;   学习如何对输入进行合法性检查和格式化;   处理单词、文本行、特殊字符和数值;   学习如何在URL、路径、标记语言和数据交换使用正则   表达式;   学习更高深的正则表达式特性的微妙之处;   理解在不同语言正则表达式的APl、语法和行为之间的   区别;   创建更好的正则表达式来满足个性化的需求。 内容简介 本书讲解了基于8种常用的编程语言使用正则表达式的经典实例。书提供了上百种可以在实战使用的实例,以帮助读者使用正则表达式来处理数据和文本。对于如何使用正则表达式来解决性能不佳、误报、漏报等常见的错误以及完成一些常见的任务,本书给出了涉及基于C#、Java、JavaScript、Perl、PHP、Python、Ruby和VB.NET等编程语言的解决方案。   本书的读者对象是对正则表达式感兴趣的软件开发人员和系统管理员。本书旨在教会读者很多新的技巧以及如何避免语言特定的陷阱,读者可以通过本书提供的实例解决方案库来解决实践的复杂问题。 作者简介 Jan Goyvaerts领导着Just Great Software公司,他在这个公司设计和开发了一些最流行的正则表达式软件。他的产品包括RegexBuddy,世界上唯一可以模拟l5种正则表达式流派特性的正则表达式编辑器,以及PowerGREP,Microsoft Windows平台上功能最强大的9rep工具。 目录: 第1章 正则表达式简介 1.1 正则表达式的定义 1.2 使用正则表达式的工具 第2章 正则表达式的基本技巧 2.1 匹配字面文本 2.2 匹配不可打印字符 2.3 匹配多个字符之一 2.4 匹配任意字符 2.5 匹配文本行起始和/或文本行结尾 2.6 匹配整个单词 2.7 Unicode代码点、属性、区块和脚本 2.8 匹配多个选择分支之一 2.9 分组和捕获匹配的子串 2.10 再次匹配先前匹配的文本 2.11 捕获和命名匹配子串 2.12 把正则表达式的一部分重复多次 2.13 选择最小和最大重复次数 2.14 消除不必要的回溯 2.15 避免重复逃逸 2.16 检查一个匹配,但不添加到整体匹配 2.17 根据条件匹配两者之一 2.18 向正则表达式添加注释 2.19 在替代文本添加字面文本 2.20 在替代文本添加正则匹配 2.21 把部分的正则匹配添加到替代文本 2.22 把匹配上下文插入到替代文本 第3章 使用正则表达式编程 3.1 在源代码使用字面正则表达式 3.2 导入正则表达式函数库 3.3 创建正则表达式对象 3.4 设置正则表达式选项 3.5 检查是否可以在目标字符串找到匹配 3.6 检查正则表达式能否整个匹配目标字符串 3.7 获取匹配文本 3.8 决定匹配的位置和长度 3.9 获取匹配文本的一部分 3.10 获取所有匹配的列表 3.11 遍历所有匹配 3.12 在过程代码对匹配结果进行验证 3.13 在另一个匹配查找匹配 3.14 替换所有匹配 3.15 使用匹配的子串来替换匹配 3.16 使用代码生成的替代文本来替换匹配 3.17 替换另一个正则式匹配的所有匹配 3.18 替换另一个正则式匹配之间的所有匹配 3.19 拆分字符串 3.20 拆分字符串,保留正则匹配 3.21 逐行查找 第4章 合法性验证和格式化 4.1 E-mail地址的合法性验证 4.2 北美电话号码的合法性验证和格式化 4.3 国际电话号码的合法性验证 4.4 传统日期格式的合法性验证 4.5 对传统日期格式进行精确的合法性验证 4.6 传统时间格式的合法性验证 4.7 检查ISO 8601格式的日期和时间 4.8 限制输入只能为字母数字字符 4.9 限制文本长度 4.10 限制文本的行数 4.11 肯定响应的检查 4.12 社会安全号码的合法性验证 4.13 ISBN的合法性验证 4.14 ZIP代码的合法性验证 4.15 加拿大邮政编码的合法性验证 4.16 英国邮政编码的合法性验证 4.17 查找使用邮局信箱的地址 4.18 转换姓名格式 4.19 信用卡号码的合法性验证 4.20 欧盟增值税代码 第5章 单词、文本行和特殊字符 5.1 查找一个特定单词 5.2 查找多个单词之一 5.3 查找相似单词 5.4 查找除某个单词之外的任意单词 5.5 查找后面不跟着某个特定单词的任意单词 5.6 查找不跟在某个特定单词之后的任意单词 5.7 查找临近单词 5.8 查找重复单词 5.9 删除重复的文本行 5.10 匹配包含某个单词的整行内容 5.11 匹配不包含某个单词的整行 5.12 删除前导和拖尾的空格 5.13 把重复的空白替换为单个空格 5.14 对正则表达式元字符进行转义 第6章 数字 6.1 整数 6.2 十六进制数字 6.3 二进制数 6.4 删除前导 6.5 位于某个特定范围之内的整数 6.6 在某个特定范围之内的十六进制数 6.7 浮点数 6.8 含有千位分隔符的数 6.9 罗马数字 第7章 URL、路径和Internet地址 7.1 URL合法性验证 7.2 在全文查找URL 7.3 在全文查找加引号的URL 7.4 在全文寻找加括号的URL 7.5 把URL转变为链接 7.6 URN合法性验证 7.7 通用URL的合法性验证 7.8 从URL提取通信协议方案 7.9 从URL抽取用户名 7.10 从URL抽取主机名 7.11 从URL抽取端口号 7.12 从URL抽取路径 7.13 从URL抽取查询 7.14 从URL抽取片段 7.15 域名合法性验证 7.16 匹配IPv4地址 7.17 匹配IPv6地址 7.18 Windows路径的合法性验证 7.19 分解Windows路径 7.20 从Windows路径抽取盘符 7.21 从UNC路径抽取服务器和共享名 7.22 从Windows路径抽取文件夹 7.23 从Windows路径抽取文件名 7.24 从Windows路径抽取文件扩展名 7.25 去除文件名的非法字符 第8章 标记语言和数据交换 8.1 查找XML风格的标签 8.2 把标签b替换为strong 8.3 删掉除em和strong之外的所有XML风格标签 8.4 匹配XML名称 8.5 添加p和br标签将纯文本转换为HTML 8.6 在XML风格的标签查找某个特定属性 8.7 向不包含cellspacing属性的 table标签添加该属性 8.8 删除XML风格的注释 8.9 在XML风格的注释查找单词 8.10 替换在CSV文件使用的分隔符 8.11 抽取某个特定列的CSV域 8.12 匹配INI段头 8.13 匹配INI段块 8.14 匹配INI名称-值对
中文名: 正则表达式经典实例 原名: Regular Expression Cookbook 作者: (美)高瓦特斯(Goyvaerts,J.) (美)利维森(Levithan,S.)译者: 郭耀 资源格式: PDF 版本: 扫描版 出版社: 人民邮电出版社书号: 9787115228321发行时间: 2010年06月01日 地区: 大陆 语言: 简体中文 简介: 编辑推荐 每个程序员都会遇到需要使用正则表达式的情况,但是要用好正则表达式却并不容易。本书提供了100多个实例,以帮助读者使用正则表达式处理数据和文本。即使有经验的用户也经常会遇到性能不佳、误报、漏报等让人挠头的错误,本书对于如何使用正则表达式来解决一些常见的问题给出了按部就班的解决方案,其包括c#、Java、JavaScript、Perl、PHP、Python、Ruby和VB.NET的实例。   本书主要包括以下内容:   通过一个精练的教程理解正则表达式的基本原理和技巧;   在不同的编程语言和脚本语言有效使用正则表达式;   学习如何对输入进行合法性检查和格式化;   处理单词、文本行、特殊字符和数值;   学习如何在URL、路径、标记语言和数据交换使用正则   表达式;   学习更高深的正则表达式特性的微妙之处;   理解在不同语言正则表达式的APl、语法和行为之间的   区别;   创建更好的正则表达式来满足个性化的需求。 内容简介 本书讲解了基于8种常用的编程语言使用正则表达式的经典实例。书提供了上百种可以在实战使用的实例,以帮助读者使用正则表达式来处理数据和文本。对于如何使用正则表达式来解决性能不佳、误报、漏报等常见的错误以及完成一些常见的任务,本书给出了涉及基于C#、Java、JavaScript、Perl、PHP、Python、Ruby和VB.NET等编程语言的解决方案。   本书的读者对象是对正则表达式感兴趣的软件开发人员和系统管理员。本书旨在教会读者很多新的技巧以及如何避免语言特定的陷阱,读者可以通过本书提供的实例解决方案库来解决实践的复杂问题。 作者简介 Jan Goyvaerts领导着Just Great Software公司,他在这个公司设计和开发了一些最流行的正则表达式软件。他的产品包括RegexBuddy,世界上唯一可以模拟l5种正则表达式流派特性的正则表达式编辑器,以及PowerGREP,Microsoft Windows平台上功能最强大的9rep工具。 目录: 第1章 正则表达式简介 1.1 正则表达式的定义 1.2 使用正则表达式的工具 第2章 正则表达式的基本技巧 2.1 匹配字面文本 2.2 匹配不可打印字符 2.3 匹配多个字符之一 2.4 匹配任意字符 2.5 匹配文本行起始和/或文本行结尾 2.6 匹配整个单词 2.7 Unicode代码点、属性、区块和脚本 2.8 匹配多个选择分支之一 2.9 分组和捕获匹配的子串 2.10 再次匹配先前匹配的文本 2.11 捕获和命名匹配子串 2.12 把正则表达式的一部分重复多次 2.13 选择最小和最大重复次数 2.14 消除不必要的回溯 2.15 避免重复逃逸 2.16 检查一个匹配,但不添加到整体匹配 2.17 根据条件匹配两者之一 2.18 向正则表达式添加注释 2.19 在替代文本添加字面文本 2.20 在替代文本添加正则匹配 2.21 把部分的正则匹配添加到替代文本 2.22 把匹配上下文插入到替代文本 第3章 使用正则表达式编程 3.1 在源代码使用字面正则表达式 3.2 导入正则表达式函数库 3.3 创建正则表达式对象 3.4 设置正则表达式选项 3.5 检查是否可以在目标字符串找到匹配 3.6 检查正则表达式能否整个匹配目标字符串 3.7 获取匹配文本 3.8 决定匹配的位置和长度 3.9 获取匹配文本的一部分 3.10 获取所有匹配的列表 3.11 遍历所有匹配 3.12 在过程代码对匹配结果进行验证 3.13 在另一个匹配查找匹配 3.14 替换所有匹配 3.15 使用匹配的子串来替换匹配 3.16 使用代码生成的替代文本来替换匹配 3.17 替换另一个正则式匹配的所有匹配 3.18 替换另一个正则式匹配之间的所有匹配 3.19 拆分字符串 3.20 拆分字符串,保留正则匹配 3.21 逐行查找 第4章 合法性验证和格式化 4.1 E-mail地址的合法性验证 4.2 北美电话号码的合法性验证和格式化 4.3 国际电话号码的合法性验证 4.4 传统日期格式

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值