注:文章原文为Dr. Charles Severance 的 《Python for Informatics》。文中代码用3.4版改写,并在本机测试通过。

11.2 用正则表达式抽取数据

  在Python中,我们可以使用findall()方法从字符串中抽取所有匹配正则表达式的子字符串。接下来我们会用一个例子,从行中抽取看起来像电子邮件地址的字符串,而不考虑行的格式。比如,我们想从下面几行字符串中拉出电子邮件地址。

From stephen.marquard@uct.ac.za Sat Jan 5 09:14:16 2008
Return-Path: <postmaster@collab.sakaiproject.org>
for <source@collab.sakaiproject.org>;
Received: (from apache@localhost)
Author: stephen.marquard@uct.ac.za

  但我们又不想为每一行编写不同的代码来分离、切片字符串。下面的程序用findall()找到包含电子邮件地址的行,然后从每一行中抽取一个或者更多的地址。

 import re
s = 'Hello from csev@umich.edu to cwen@iupui.edu about the meeting @2PM'
lst = re.findall('\S+@\S+', s)
print(lst)

  findall()方法查找它的第二参数s并返回所有类似电子邮件地址的字符串。这里我们用了两个字符序列"\S"来匹配非空白字符。其输出将会是:

['csev@umich.edu', 'cwen@iupui.edu']

  这个正则表达式表明我们正在查找这样一个字符串:由一个以上非空白字符开头,紧跟着@符,然后再跟着一个以上非空白字符的字符串。而且,“\S"表达式将匹配所有的非空字符(这在正则表达式中被叫做”贪婪的“)。

  这个正则表达式将两次匹配到符合要求的字符串(cesv@umich.edu 和 cwen@iupui.edu),但它不会匹配”@2PM“,因为这个字符串的@符之前没有非空白字符。我们可以在程序中利用这个正则表达式读取文件的所有行,并打印出任何看起来像电子邮件地址的字符串:

 import re
hand = open('mbox-short.txt')
for line in hand:
line = line.rstrip()
x = re.findall('\S+@\S+', line)
if len(x) > 0 :
print(x)

  我们读取每一行,然后抽取所有匹配这个正则表达式的字符串。因为findall()返回的是一个列表,所以我们只要检查这个列表的元素个数是否大于零就可判断并打印出至少一个以上的邮件地址。如果我们运行这个程序,将会得到以下输出:

['wagnermr@iupui.edu']
['cwen@iupui.edu']
['<postmaster@collab.sakaiproject.org>']
['<200801032122.m03LMFo4005148@nakamura.uits.iupui.edu>']
['<source@collab.sakaiproject.org>;']
['<source@collab.sakaiproject.org>;']
['<source@collab.sakaiproject.org>;']
['apache@localhost)']
['source@collab.sakaiproject.org;']

  输出的有些电子邮件地址的开头或结尾有一些不正确的字符像"<"或";"。而我们声明只对以字母或数字开头,以字母结尾的字符串感兴趣。

  为做到这一点,我们使用另一特性的正则表达式。方括号被用来表示多个可接受字符的集合。在一定程度上,"\S"是要求匹配非空白字符,现在我们需要更加清楚的匹配规则。

  下面是我们新的正则表达式:

[a-zA-Z0-9]\S*@\S*[a-zA-Z]

  这个表达式变得有点复杂,这让你明白为什么对正则表达式而言,它拥有自己的语言。这个表达式表示我们要找的字符串是这样的:以字母(大小写均可)或数字开头的,接着是任意个非空白字符,可以是零个,中间是@符,接下来又是非空白字符,最后是字母结尾。其中[a-z]和[A-Z]分别表示26个大小写字母,[0-9]表示10个数字,"\S*"表示任意个非空白字符。这里用星号代替加号,是因为方括号内已有一个字符。记住,星号和加号只应用于其紧邻的左侧字符。

  如果我们在程序中使用这个正则表达式,我们获得的数据将更加干净:

 import re
hand = open('mbox-short.txt')
for line in hand:
line = line.rstrip()
x = re.findall('[a-zA-Z0-9]\S*@\S*[a-zA-Z', line)
if len(x) > 0 :
print(x)

['wagnermr@iupui.edu']
['cwen@iupui.edu']
['postmaster@collab.sakaiproject.org']
['200801032122.m03LMFo4005148@nakamura.uits.iupui.edu']
['source@collab.sakaiproject.org']
['source@collab.sakaiproject.org']
['source@collab.sakaiproject.org']
['apache@localhost']

  请注意“source@collab.sakaiproject.org”这几行,我们的新表达式消除了其尾部的">;"两个字符。这是因为我们的表达式添加[a-zA-Z]后,要求正则表达式的解析器找到的字符串必须以字母结尾,所以它就简单的停在了"g"上,而剔除了">;"。

  同时需要注意的是,程序输出的是Python的列表,列表中的每个元素都是字符串。

  

Python for Informatics 第11章 正则表达式三(译)的更多相关文章

  1. Python for Informatics 第11章 正则表达式五(译)

    注:文章原文为Dr. Charles Severance 的 <Python for Informatics>.文中代码用3.4版改写,并在本机测试通过. 11.4 转义字符 之前我们在正 ...

  2. Python for Informatics 第11章 正则表达式六(译)

    注:文章原文为Dr. Charles Severance 的 <Python for Informatics>.文中代码用3.4版改写,并在本机测试通过. 11.7 调试 Python有一 ...

  3. Python for Informatics 第11章 正则表达式四(译)

    注:文章原文为Dr. Charles Severance 的 <Python for Informatics>.文中代码用3.4版改写,并在本机测试通过. 11.3 组合查询和抽取 如果我 ...

  4. Python for Informatics 第11章 正则表达式二(译)

    注:文章原文为Dr. Charles Severance 的 <Python for Informatics>.文中代码用3.4版改写,并在本机测试通过. 11.1 正则表达式的字符匹配 ...

  5. Python for Informatics 第11章 正则表达式一(译)

    注:文章原文为Dr. Charles Severance 的 <Python for Informatics>.文中代码用3.4版改写,并在本机测试通过. 目前为止,我们一直在通读文件,查 ...

  6. 《Python学习手册 第五版》 -第11章 赋值、表达式和打印

    上一章对Python的语句和语法已经进行了基本的说明,接下来就是每个章节的详细说明,本章的主要内容就是标题中涵盖的三点:赋值语句.表达式语句.打印语句 本章重点内容如下: 1.赋值语句 1)赋值语句的 ...

  7. 路飞学城—Python爬虫实战密训班 第三章

    路飞学城—Python爬虫实战密训班 第三章 一.scrapy-redis插件实现简单分布式爬虫 scrapy-redis插件用于将scrapy和redis结合实现简单分布式爬虫: - 定义调度器 - ...

  8. Python for Infomatics 第12章 网络编程三(译)

    注:文章原文为Dr. Charles Severance 的 <Python for Informatics>.文中代码用3.4版改写,并在本机测试通过. 12.5 HTML分析和网页抓取 ...

  9. python中关于正则表达式三

    2015年8月14日 11:10 7.2正则表达式操作 正则表达式使用反斜杠字符'\'来暗示一些特殊的形式或者允许特殊的字符使用但是没有调用它们特殊的意思.在字符串常量中的相同目标的字符的python ...

随机推荐

  1. 三、jQuery--jQuery基础--jQuery基础课程--第7章 jQuery 动画特效

    1.调用show()和hide()方法显示和隐藏元素 show()和hide()方法用于显示或隐藏页面中的元素,它的调用格式分别为:$(selector).hide(speed,[callback]) ...

  2. 给UILabel设置不同的字体和颜色

    NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:@"Using NSAt ...

  3. JQ 特效下拉列表 写出与css一样的效果

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. 数据结构和算法 – 9.二叉树和二叉查找树

      9.1.树的定义   9.2.二叉树 人们把每个节点最多拥有不超过两个子节点的树定义为二叉树.由于限制子节点的数量为 2,人们可以为插入数据.删除数据.以及在二叉树中查找数据编写有效的程序了. 在 ...

  5. Oracle Redo Log

    http://blog.itpub.net/27039319/viewspace-2120623/ 11.2和11.2以下的区别:http://blog.itpub.net/27039319/view ...

  6. C#接扣和抽象类

    什么是接口? 接口是包含一组虚方法的抽象类型,其中每一种方法都有其名称.参数和返回值.接口方法不能包含任何实现,CLR允许接口可以包含事件.属性.索引器.静态方法.静态字段.静态构造函数以及常数.但是 ...

  7. 对Java内存模型即JMM的理解

    类似物理上的计算机系统,Java虚拟机规范中也定义了一种Java内存模型,即Java Memory Model(JMM),来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能 ...

  8. ASP.NET Web Api 实现数据的分页(转载)

    转载地址:http://www.cnblogs.com/fzrain/p/3542608.html 前言 这篇文章我们将使用不同的方式实现手动分页(关于高端大气上档次的OData本文暂不涉及,但有可能 ...

  9. HDU1899 Sum the K-th's(树状数组)

    枚举,每次增加点,删除点 #include<cstdio> #include<iostream> #include<cstdlib> #include<cst ...

  10. mac os x10.10 安装thrift

    http://thrift.apache.org/docs/install/ 一:安装最新版(自动安装) 最简单的是用homebrew进行安装 安装homebrew 在终端输入ruby -e &quo ...