第一章正则表达式

一、正则表达式

按照练习 1-1~1-12 的要求创建正则表达式。

1-1 识别后续的字符串:“bat”、“bit”、“but”、“hat”、“hit”或者“hut”。

>>> import re
>>> data = "bat, bit, but, hat, hit, hut"
>>> patt1_1 = '[bh][aiu]t'
>>> re.findall(patt1_1, data)
['bat', 'bit', 'but', 'hat', 'hit', 'hut']

1-2 匹配由单个空格分隔的任意单词对,也就是姓和名。

>>> patt1_2 = '\w+ \w+'
>>> data1_2 = """
... zhang san
... li si
... wang wu
... """
>>> re.findall(patt1_2, data1_2)
['zhang san', 'li si', 'wang wu']

1-3 匹配由单个逗号和单个空白符分隔的任何单词和单个字母,如姓氏的首字母。

>>> patt1_3 = '[, ]?(\w+)[, ]?'
>>> data1_3 = """
... zhang san
... li si
... wang wu
... """
>>> re.findall(patt1_3, data1_3)
['zhang', 'san', 'li', 'si', 'wang', 'wu']

1-4 匹配所有有效 Python 标识符的集合。

>>> patt1_4 =r'\b[A-Za-z_][A-Za-z0-9_]*\b'  # \b 是声明单词开头
>>> data1_4 = '9wat Ea43 _oa5 *uyz1 foo P 0 p'
>>> re.findall(patt1_4, data1_4)
['Ea43', '_oa5', 'uyz1', 'foo', 'P', 'p']

1-5 根据读者当地的格式,匹配街道地址(使你的正则表达式足够通用,来匹配任意数
量的街道单词,包括类型名称)。例如,美国街道地址使用如下格式:1180 Bordeaux
Drive。使你的正则表达式足够灵活,以支持多单词的街道名称,如 3120 De la Cruz
Boulevard。

patt1_5 = r"\d+\s([A-Za-z]+\s)"

1-6 匹配以“www”起始且以“.com”结尾的简单 Web 域名;例如,www://www. yahoo.com/。

patt1_6 = r"^www[\S]*\.com$"

选做题:你的正则表达式也可以支持其他高级域名,如.edu、.net 等(例如,
http://www.foothill.edu)。

patt1_6 = r"www[\S]*\.(com|edu|net)$"

1-7 匹配所有能够表示 Python 整数的字符串集。

patt1_7 = r"[-+]?\d+"

1-8 匹配所有能够表示 Python 长整数的字符串集。

patt1_8 = r"[-+]?\d+[lL]"

1-9 匹配所有能够表示 Python 浮点数的字符串集。

patt1_9 = r"[-+]?\d+\.\d*([e]\d+)?"

1-10 匹配所有能够表示 Python 复数的字符串集。

patt1_10 = r"([-+]?\d+\.\d*([e]\d+)?)?[+-]?[-+]?\d+\.\d*([e]\d+)?[Jj]"

1-11 匹配所有能够表示有效电子邮件地址的集合(从一个宽松的正则表达式开始,然
后尝试使它尽可能严谨,不过要保持正确的功能)。

"""
email 地址有两部分,user@domin.com 不区分大小写
user 包括小写字母数字下划线点,英文字母开头
域名,各国文字的特定字符集、英文字母、数字及“-”(即连字符或减号)任意组合而成,
但开头及结尾均不能含有“-”,“-”不能连续出现 。
域名最长可达60个字节(包括后缀.com、.net、.org等)
"""
patt1_11 = r"[a-z][a-z0-9]*[_.]?[a-z0-9]+@([a-z0-9]+[-]?[a-z0-9]+\.)+\w"

1-12 匹配所有能够表示有效的网站地址的集合(URL)(从一个宽松的正则表达式开始,
然后尝试使它尽可能严谨,不过要保持正确的功能)。

patt1_12 = r"[a-z]+\://([a-z0-9]+[-]?[a-z0-9]+\.)+[\:\d+]?[/\w+]*"

1-13 type()。内置函数 type()返回一个类型对象,如下所示,该对象将表示为一个 Pythonic
类型的字符串。

>>> type(0)
<type 'int'>
>>> type(.34)
<type 'float'>
>>> type(dir)
<type 'builtin_function_or_method'>

创建一个能够从字符串中提取实际类型名称的正则表达式。函数将对类似于<type
‘int’ >的字符串返回 int(其他类型也是如此,如 ‘float’ 、‘builtin_function_or_method’ 等)。
注意:你所实现的值将存入类和一些内置类型的__name__属性中。

patt = r"^<class '([A-Za-z0-9_]+)'>$"

1-14 处理日期。1.2 节提供了来匹配单个或者两个数字字符串的正则表达式模式,来表示 1~9 的月份(0?[1-9])。创建一个正则表达式来表示标准日历中剩余三个月的数字。

# 格式 MM/DD/[YY|YYYY]
patt = r"[01]?[0-9]/[0-3]?[0-9]/(\d{2}|\d{4})

1-15 处理信用卡号码。1.2 节还提供了一个能够匹配信用卡(CC)号码([0-9]{15,16})
的正则表达式模式。然而,该模式不允许使用连字符来分割数字块。创建一个允
许使用连字符的正则表达式,但是仅能用于正确的位置。例如,15 位的信用卡号
码使用 4-6-5 的模式,表明 4 个数字-连字符-6 个数字-连字符-5 个数字;16 位的
信用卡号码使用 4-4-4-4 的模式。记住,要对整个字符串进行合适的分组。选做题:
有一个判断信用卡号码是否有效的标准算法。编写一些代码,这些代码不但能够
识别具有正确格式的号码,而且能够识别有效的信用卡号码。

patt = (\d{4}-\d{6}-\d{5})|(\d{4}-\d{4}-\d{4}-\d{4})

使用 gendata.py。下面一组练习(1-16~1-27)专门处理由 gendata.py 生成的数据。
在尝试练习 1-17 和 1-18 之前,读者需要先完成练习 1-16 以及所有正则表达式。
1-16 为 gendata.py 更新代码,使数据直接输出到 redata.txt 而不是屏幕。

# 代码 gendata.py#!/usr/bin/env python
"""生成随机 登陆 日志包括 日期 - 邮箱地址
"""from random import randrange, choice
from string import ascii_lowercase as lc
from time import ctimetlds = ('com', 'edu', 'net', 'org', 'gov')
txt = ""
for i in range(randrange(5, 11)):dtint = randrange(2**32)      # 选取随机数dtstr = ctime(dtint)          # 选取日期llen = randrange(4, 8)        # login 长度login = ''.join(choice(lc) for j in range(llen))dlen = randrange(llen, 13)    # 域名 长度dom = ''.join(choice(lc) for j in range(dlen))txt += f'{dtstr}::{login}@{dom}.{choice(tlds)}::{dtint}-{llen}-{dlen}'+"\n"
with open('redata.txt', 'w') as f:f.write(txt)

1-17 判断在 redata.txt 中一周的每一天出现的次数(换句话说,读者也可以计算所选择
的年份中每个月中出现的次数)。

txt = """
Sun Sep 22 09:07:03 1985::kaywlrk@iavxlyfv.net::496199223-7-8
Thu Jul  5 08:10:06 2018::dpsv@gkpv.edu::1530749406-4-4
Mon May  8 08:21:54 2017::ostgv@ckigpoyxfcx.net::1494202914-5-11
Thu Nov 30 01:13:41 2017::erbw@tbzxnjougvcg.com::1511975621-4-12
Tue Mar 15 00:47:50 2072::qkbg@xgcmhyg.net::3225199670-4-7
Fri Nov  3 03:56:11 2079::yvsvu@qlituwxpqg.com::3466180571-5-10
Thu Jun 28 01:59:17 2035::thgoje@pdgqavkfscx.net::2066579957-6-11
Thu Jan 14 10:49:02 2010::rihgedo@ybxvbjelabyk.com::1263437342-7-12
Sat Jul  6 09:00:58 2030::izdnxtf@krfnrxmu.edu::1909530058-7-8
"""
import re
patt = r"(\w{3})\s+\w{3}\s+\d{1,2}"
day = re.findall(patt, txt)
day_dict={}
for i in day:day_dict[i] = day_dict.get(i, 0) + 1
print(day_dict)

1-18 通过确认整数字段中的第一个整数匹配在每个输出行起始部分的时间戳,确保在
redata.txt 中没有数据损坏

txt = """
Sun Sep 22 09:07:03 1985::kaywlrk@iavxlyfv.net::496199223-7-8
Thu Jul  5 08:10:06 2018::dpsv@gkpv.edu::1530749406-4-4
Mon May  8 08:21:54 2017::ostgv@ckigpoyxfcx.net::1494202914-5-11
Thu Nov 30 01:13:41 2017::erbw@tbzxnjougvcg.com::1511975621-4-12
Tue Mar 15 00:47:50 2072::qkbg@xgcmhyg.net::3225199670-4-7
Fri Nov  3 03:56:11 2079::yvsvu@qlituwxpqg.com::3466180571-5-10
Thu Jun 28 01:59:17 2035::thgoje@pdgqavkfscx.net::2066579957-6-11
Thu Jan 14 10:49:02 2010::rihgedo@ybxvbjelabyk.com::1263437342-7-12
Sat Jul  6 09:00:58 2030::izdnxtf@krfnrxmu.edu::1909530058-7-8
"""
import re
from time import ctime
patt = r"(\w{3}\s+\w{3}\s+\d{1,2}\s+\d{2}:\d{2}:\d{2}\s+\d{4})::.*::(\d+)-\d-\d+"
day_list = re.findall(patt, txt)
for i in day_list:if i[0] == ctime(int(i[1])):print(True)

创建以下正则表达式。
1-19 提取每行中完整的时间戳。

patt = r"(\w{3}\s+\w{3}\s+\d{1,2}\s+\d{2}:\d{2}:\d{2}\s+\d{4})"

1-20 提取每行中完整的电子邮件地址。

patt = r"\w+@\w+\.\w+"

1-21 仅仅提取时间戳中的月份。

patt = r"\w{3}\s+(\w{3})\s+\d{1,2}\s+\d{2}:\d{2}:\d{2}\s+\d{4}"

1-22 仅仅提取时间戳中的年份。

patt = r"\w{3}\s+\w{3}\s+\d{1,2}\s+\d{2}:\d{2}:\d{2}\s+(\d{4})"

1-23 仅仅提取时间戳中的时间(HH:MM:SS)。

patt = r"\w{3}\s+\w{3}\s+\d{1,2}\s+(\d{2}:\d{2}:\d{2})\s+(\d{4})"

1-24 仅仅从电子邮件地址中提取登录名和域名(包括主域名和高级域名一起提取)。

patt = r"(\w+)@(\w+\.\w+)"

1-25 仅仅从电子邮件地址中提取登录名和域名(包括主域名和高级域名)。

patt = r"(\w+)@(\w+\.\w+)"

1-26 使用你的电子邮件地址替换每一行数据中的电子邮件地址。

 newtxt = re.sub(patt, "mayun@alibaba.com", txt)

1-27 从时间戳中提取月、日和年,然后以“月,日,年”的格式,每一行仅仅迭代一次。
处理电话号码。对于练习 1-28 和 1-29,回顾 1.2 节介绍的正则表达式\d{3}-\d{3}-\d{4}
它匹配电话号码,但是允许可选的区号作为前缀。更新正则表达式,使它满足以下条件。

patt = r"\w{3}\s+(\w{3})\s+(\d{1,2})\s+\d{2}:\d{2}:\d{2}\s+(\d{4})"

1-28 区号(三个整数集合中的第一部分和后面的连字符)是可选的,也就是说,正则
表达式应当匹配 800-555-1212,也能匹配 555-1212。

patt  = r"(\d{3})?-\d{3}-\d{4}"

1-29 支持使用圆括号或者连字符连接的区号(更不用说是可选的内容);使正则表达式
匹配 800-555-1212、555-1212 以及(800)555-1212。正则表达式应用程序。下面练习在处理在线数据时生成了有用的应用程序脚本。

patt = r"((\d{3})?-\d{3}-\d{4})|(\(\d{3}\)\s+\d{3}-\d{4}"

下面三道题不会做,没太看懂题目。

1-30 生成 HTML。提供一个链接列表(以及可选的简短描述),无论用户通过命令
行方式提供、通过来自于其他脚本的输入,还是来自于数据库,都生成一个
Web 页面(.html),该页面包含作为超文本锚点的所有链接,它可以在 Web 浏
览器中查看,允许用户单击这些链接,然后访问相应的站点。如果提供了简短
的描述,就使用该描述作为超文本而不是 URL。
1-31 tweet 精简。有时候你想要查看由 Twitter 用户发送到 Twitter 服务的 tweet 纯文本。
创建一个函数以获取 tweet 和一个可选的“元”标记,该标记默认为 False,然
后返回一个已精简过的 tweet 字符串,即移除所有无关信息,例如,表示转推的
RT 符号、前导的“.”符号,以及所有#号标签。如果元标记为 True,就返回一
个包含元数据的字典。这可以包含一个键“RT”,其相应的值是转推该消息的用
户的字符串元组和/或一个键“#号标签”(包含一个#号标签元组)。如果值不存
在(空元组),就不要为此创建一个键值条目。
1-32 亚马逊爬虫脚本。创建一个脚本,帮助你追踪你最喜欢的书,以及这些书在亚马
逊上的表现(或者能够追踪图书排名的任何其他的在线书店)。例如,亚马逊对于
任何一本图书提供以下链接:http://amazon.com/dp/ISBN(例如,http://amazon.com/
dp/0132678209)。读 者可以改变域名,检查亚马逊在其他国家的站点上相同的图
书排名,例如德国(.de)、法国(.fr)、日本(.jp)、中国(.cn)和英国(.co.uk)。
使用正则表达式或者标记解析器,例如 BeautifulSoup、lxml 或者 html5lib 来解析
排名,然后让用户传入命令行参数,指明输出是否应当在一个纯文本中,也许包
含在一个电子邮件正文中,还是用于 Web 的格式化 HTML 中。

正则表达式习题解答-Python核心编程3 第一章相关推荐

  1. python核心编程第五章课后习题

    答案自己做的,如果有问题欢迎大家提出来. 5-1   整型.讲讲python普通整型和长整型的区别. 长整型是普通整型的超集,python中的长整型类型能表达的数值仅仅与你机器支持的虚拟内存大小有关. ...

  2. python 核心编程第5章(习题)

    1.标准类型运算符. 写一段脚本,输入一个测验成绩,根据下面的标准,输出他的评分成绩(A-F). #coding:utf8 a = raw_input() a = int(a) if (a > ...

  3. python 核心编程 第十三章

    python面对对象 类和实例:类是对象的定义,实例是真真的实物. 创建一个类: class AddrBookEnttry(object):def __init__(self, nm, ph):sel ...

  4. 【3】python核心编程 第六章-序列:字符串、列表和元组

    1.序列类型操作符 1 序列操作符 作用 2 seq[ind] 获得下标为ind 的元素 3 seq[ind1:ind2] 获得下标从ind1 到ind2 间的元素集合 4 seq * expr 序列 ...

  5. python核心编程-第六章-个人笔记(一)

    2019独角兽企业重金招聘Python工程师标准>>> 0.    序列包括字符串.列表和元组三种类型 1.    序列 1.0  序列的每一个元素可以通过指定一个偏移量的方式得到, ...

  6. Python核心编程第四章

    2019独角兽企业重金招聘Python工程师标准>>> 4.1 python对象 三个特性:身份.类型.值 4.2 标准类型 int bool longint float cmp s ...

  7. Python核心编程-第2章-网络编程(1)

    一.基本概念 1.嵌套字 套接字是计算机网络数据结构,它体现了上节中所描述的"通信端点"的概念.在任何类型的通信开始之前,网络应用程序必须创建套接字.可以将它们比作电话插孔,没有它 ...

  8. 【0】python核心编程,第二章

    1.print语句也支持将输入重定向到文件,示例: 1 logfile = open('/tmp/mylog.txt', 'a') 2 print >> logfile, 'Fatal e ...

  9. python核心编程-第六章-个人笔记(二)

    2019独角兽企业重金招聘Python工程师标准>>> 3.11.2  in操作符和index() 先看一段代码 >>> 'record' in music_med ...

最新文章

  1. 服务器配置—开网站空间
  2. firefox如何不让网站登录失效_Firefox Preview 4开放下载:引入登录管理、热门网站等功能...
  3. 关于SAP物料的历史库存
  4. Python3快速入门----(3) dict(字典结构)
  5. NSNotification、delegate和KVO的区别
  6. 升级版的数据透视表!用一工具,做出了HR羡慕的人力数据分析
  7. 轨迹相似性度量之基于Hausdorff与LCSS的理解
  8. 【翻译】sql注入方式
  9. 一步一步学Silverlight 2系列(27):使用Brush进行填充
  10. Docker生产环境配置——设置direct-lvm模式
  11. JS中的attribute和property的区别和联系
  12. 高级变量类型 ---- 字符串
  13. Web Workers API
  14. mysql创建数据库并创建表
  15. PHP导出Excel时数据量过大的问题
  16. python换零钱_python动态规划-零钱兑换
  17. 【已解决】模拟人生4(Sims4) 启动失败 orangeEmu.dll及应用程序错误0x0000142
  18. zigbee 之 路由
  19. matlab中eye函数、ones函数
  20. 设计巴特沃斯滤波器实现高通滤波

热门文章

  1. Android ART 即时 (JIT) 编译器详解
  2. 数组和链表分别比较适合用于什么场景
  3. 面试题:数组和链表的区别
  4. good man or bad man?
  5. Hazel轻松管理文件
  6. 手机PDF转换器如何实现PPT转换PDF格式
  7. 三种通信方式——单工、半双工和双工通信
  8. 小心c语言中的无符号类型-尤其是涉及到大小比较
  9. 苹果服务器维护不能刷机,iphone刷机失败不开机报错维修方法分享
  10. java 邮件收发_java中javamail收发邮件实现方法