15-1. 识别下列字符串:“bat,” “bit,” “but,” “hat,” “hit,” 或 “hut”

from re import match

word = raw_input('input: ')
m = match('^[bh][aiu]t$', word)
if m is not None:
print m.group()
else:
print 'not match'

15–2. 匹配用一个空格分隔的任意一对单词,比如,名和姓。

from re import match

name = raw_input('input: ')
m = match('.+\s.+', name) #或者'\b\w+ \w+\b'
if m is not None:
print m.group()
else:
print 'not match'

15–3. 匹配用一个逗号和一个空格分开的一个单词和一个字母。例如,英文人名中的姓和名
的首字母。

from re import match

name = raw_input('input: ')
m = match('.+, \w', name) # 或者 '.+,\s.+'
if m is not None:
print m.group()
else:
print 'not match'

15-4 匹配所有合法的 Python 标识符。

from re import match

n = raw_input('input: ')
m = match('^[_a-zA-Z][_\w]*', n) # r'\b[a-zA-Z_](\w|_)*\b'
if m is not None:
print m.group()
else:
print 'not match'

15–5. 请根据您(读者)本地关于地址的格式写法匹配一个街道地址(你写出的正则表达式要
尽可能通用以匹配任意数目的表示街道名字的单词,包括类型指示)。比如,美国的街道地址使用这
样的格式:1180 Bordeaux Drive. 使你写的正则表达式尽可能通用,要求能够匹配多个单词的街道
名字,如:3120 De la Cruz Boulevard.

from re import match

n = raw_input('input: ')
m = match('\d+(\s[A-Za-z]+)+', n)
if m is not None:
print m.group()
else:
print 'not match'

15–6. 匹配简单的以“www.”开头,以“.com”作结尾的 Web 域名,例如:www.yahoo.com. 附
加题:使你写的正则表达式还支持其他顶级域名:.edu, .net 等,比如:www.ucsc.edu.

from re import match

n = raw_input('input: ')
m = match('^w{3}\.\w+\.(com|edu|net)$', n)
if m is not None:
print m.group()
else:
print 'not match'

15-7. 匹配全体 Python 整数的字符串表示形式的集合。

from re import match

n = raw_input('input: ')
m = match('(([\da-fA-F]+)|(( *\d+ *)+))', n)
if m is not None:
print m.group()
else:
print 'not match'

15–8. 匹配全体 Python 长整数的字符串表示形式的集合。

from re import match

n = raw_input('input: ')
m = match('( *\d+[lL] *)+', n)
if m is not None:
print m.group()
else:
print 'not match'

15–9. 匹配全体 Python 浮点数的字符串表示形式的集合。

from re import match

n = raw_input('input: ')
m = match('\d+(\.\d)*', n)
if m is not None:
print m.group()
else:
print 'not match'

15–10. 匹配全体 Python 复数的字符串表示形式的集合。

from re import match

n = raw_input('input: ')
m = match('( *\d*\+*(\dj)+ *)+', n)
if m is not None:
print m.group()
else:
print 'not match'

15–11. 匹配所有合法的电子邮件地址(先写出一个限制比较宽松的正则表达式,然后尽可能加
强限制条件,但要保证功能的正确性)。

from re import match

n = raw_input('input: ')
m = match('\w+@\w+(.com)$', n)
if m is not None:
print m.group()
else:
print 'not match'

15–12.匹配所有合法的 Web 网站地址(URLs)(先写出一个限制比较宽松的正则表达式,然后尽
可能加强限制条件,但要保证功能的正确性)。

from re import match

n = raw_input('input: ')
m = match('^www.\w+(.com|.net|.edu)$', n)
if m is not None:
print m.group()
else:
print 'not match'

15–13. type(). type()内建函数返回一个对象类型,此对象显示为 Python 的字符串形式,
如下所示:
>>> type(0)
<type 'int'>
>>> type(.34)
<type 'float'>
>>> type(dir)
<type 'builtin_function_or_method'>
请写一个正则表达式,能从这个字符串中提取出类型的名字。 你的函数能实现以下功能:如
果以字符串“<type 'int'>”做输入,会返回类型“int”.(返回其他类型也同理,如,返回类型‘float’,
‘builtin_function_or_method’等) 提示:正确的结果保存在类和某些内建类型的__name__属性
里。

from re import match

n = type(.34)
m = match("<type '(\w+)'>", str(n))
if m is not None:
print m.group(1)

15–14.正则表达式。在 15.2 小节里,我们给出一个匹配由一位或两位数字代表一月到九月的
字符串形式(“0?[1-9]”)。 请写出一个正则表达式表示标准日历上其它的三个月(十月、十一月、
十二月)。

from re import match

n = raw_input('input: ')
m = match('^(0?[1-9])$|^(10|11|12)$', n)
if m is not None:
print m.group()
else:
print 'not match'

5–15. 正则表达式。在 15.2 小节里,我们给出一个匹配信用卡卡号的模式:( “[0-9]{15,16}”).
但这个模式不允许用连字符号分割信用卡卡号中的数字。请写出一个允许使用连字符的正则表达式,
但要求连字符必须出现在正确的位置。例如,15 位的信用卡卡号的格式是 4-6-5,表示四个数字,一
个连字符,后面接六个数字、一个连字符,最后是五个数字。16 位的信用卡卡号的格式是 4-4-4-4,
数位不足时,添 0 补位。附加题:有一个用于确定某个信用卡卡号是否合法的算法。请写一段代码,
它不但能识别格式正确的信用卡卡号,还能验证它的有效性。

from re import match

n = raw_input('input: ')
m = match('^(\d{4}-\d{4}-\d{4}-\d{4})|(\d{4}-\d{6}-\d{5})$', n)
if m is not None:
print m.group()
else:
print 'not match'

下面几个问题(练习 15–16 到 15–27)专门处理 gendata.py 生成的数据。在做练习 15–17 和
15–18 之前,请先把练习 15–16 和所有正则表达式做出来。

15-16.修改gendata.py的代码,使数据直接写入文件redata.txt中,而不是输出到屏幕上。

from random import randint, choice
from string import lowercase
from sys import maxint
from time import ctime
from os import linesep doms = ('com', 'edu', 'net', 'org', 'gov')
f = open('redata.txt', 'w') for i in range(randint(5, 10)):
dtint = randint(0, maxint-1)
dtstr = ctime(dtint) shorter = randint(4, 7)
em = ''
for j in range(shorter):
em += choice(lowercase) longer = randint(shorter, 12)
dn = ''
for j in range(longer):
dn += choice(lowercase) st = '%s::%s@%s.%s::%d-%d-%d' % (dtstr, em,
dn, choice(doms), dtint, shorter, longer)
st += linesep
f.write(st) f.close()
print 'done'

15–17. 统计生成的 redata.txt 文件中,星期中的每一天出现的次数(或统计各月份出现的次
数)。

import re

week = {}.fromkeys(('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'), 0)
st = '^(' + '|'.join(week.keys()) + ')' with open('redata.txt') as f:
for line in f:
m = re.match(st, line)
if m is not None:
week[m.group()] += 1
print week

15–18.通过检查每个输出行中整数字段部分的第一个整数是否和该行开头的时间戳相匹配来
验证 redata.txt 中的数据是否完好。

import re
from time import mktime, strptime with open('redata.txt') as f:
for line in f:
m = re.match('(.+)::.+::(\d+)', line)
if m is not None:
time1 = mktime(strptime(m.group(1)))
time2 = float(m.group(2))
if time1 == time2:
print line, '...well'

15–19. 提取出每行中完整的时间戳字段。

import re

with open('redata.txt') as f:
for line in f:
m = re.match('.+::(.+)::(\d+)', line)
if m is not None:
print m.group(1)

15–20. 提取出每行中完整的电子邮件地址。

import re

with open('redata.txt') as f:
for line in f:
m = re.match('.+::(.+)::(\d+)', line)
if m is not None:
print m.group(1)

15–21. 只提取出时间戳字段中的月份。

import re

with open('redata.txt') as f:
for line in f:
m = re.match('.+? (.+?) .+', line)
if m is not None:
print m.group(1)

15-22. 只提取出时间戳字段中的年份。

import re

with open('redata.txt') as f:
for line in f:
m = re.match('.+ (.+?)::', line)
if m is not None:
print m.group(1)

15–23. 只提取出时间戳字段中的值(格式:HH:MM:SS)。

import re

with open('redata.txt') as f:
for line in f:
m = re.match('.+(\d\d:\d\d:\d\d)', line)
if m is not None:
print m.group(1)

15-24. 只从电子邮件地址中提取出登录名和域名(包括主域名和顶级域名,二者连在一起)。

import re

with open('redata.txt') as f:
for line in f:
m = re.search('::(.+)@(.+)::', line)
if m is not None:
print m.group(1), m.group(2)

15-25. 只从电子邮件地址中提取出登录名和域名(包括主域名和顶级域名,二者分别提取)。

def splitLoginNameAndDomainName(fileObj):
  EMailAddrPattern = re.compile(r'::([a-z]+)@([a-z]+\.[a-z]+)::')
while True:
  line = fileObj.readline()
if line:
  match = EMailAddrPattern.search(line)
  print ' '.join([match.group(1), match.group(2)])
else:
  break

15–26. 将每行中的电子邮件地址替换为你自己的电子邮件地址。

import re

email ='test@yahoo.jp'
ls = [] with open('redata.txt') as f:
for line in f:
ls.append(re.sub('\w+@.+::', email + '::', line)) with open('redata', 'w') as f:
f.write(''.join(ls))

15–27. 提取出时间戳中的月、日、年,并按照格式“月 日,年”显示出来,且每行仅遍
历一次。

import re

with open('redata.txt') as f:
for line in f:
m = re.match('\w+ (\w+ \w+) .+ (\d+)', line)
if m is not None:
print '%s, %s' % (m.group(1), m.group(2))

我们在小节 15.2 中使用的一个匹配电话号码的正则表达式,其中电话号码允许包含可选的区号
前缀 : \d{3}-\d{3}-\d{4}. 请在练习 15–28 和 15–29 中, 修改这个正则表达式,使它满足:
15–28.区号(第一组的三个数字和它后面的连字符)是可选的,即,你写的正则表达式对
800-555-1212 和 555-1212 都可以匹配。

import re

n = raw_input('input: ')
m = re.match('(\d{3}-)*\d{3}-\d{4}', n)
if m is not None:
print m.group()
else:
print 'Not match'

15–29.区号中可以包含圆括号或是连字符,而且它们是可选的,就是说你写的正则表达式可以
匹配 800-555-1212, 或 555-1212, 或(800) 555-1212.

from re import match

n = raw_input('input: ')
m = match('(\d{3}-|\(\d{3}\))*\d{3}-\d{4}', n)
if m is not None:
print m.group()
else:
print 'not match'

做题的过程中学会了很多,本来以为正则特别难,通过这次练习,现在已经不怕它了。

Python核心编程(第二版)正则表达式练习题解的更多相关文章

  1. python核心编程第二版笔记

    python核心编程第二版笔记由网友提供:open168 python核心编程--笔记(很详细,建议收藏) 解释器options:1.1 –d   提供调试输出1.2 –O   生成优化的字节码(生成 ...

  2. Python核心编程(第二版)PDF

    Python核心编程(第二版) 目录 第1部分 Python核心第1章 欢迎来到Python世界1.1 什么是Python1.2 起源1.3 特点1.3.1 高级1.3.2 面向对象1.3.3 可升级 ...

  3. 拒绝从入门到放弃_《Python 核心编程 (第二版)》必读目录

    目录 目录 关于这本书 必看知识点 最后 关于这本书 <Python 核心编程 (第二版)>是一本 Python 编程的入门书,分为 Python 核心(其实并不核心,应该叫基础) 和 高 ...

  4. Python核心编程第二版(中文).pdf 目录整理

    python核心编程目录 Chapter1:欢迎来到python世界!-页码:7 1.1什么是python 1.2起源  :罗萨姆1989底创建python 1.3特点 1.3.1高级 1.3.2面向 ...

  5. 面向对象——python核心编程第二版

    类与实例 类与实例相互关联着:类是对象的定义,而实例是"真正的实物",它存放了类中所定义的对象的具体信息. class MyData(object): pass >>& ...

  6. python 核心编程第二版 课后习题 第11章

    11-3 函数.在这个练习中,我们将实现 max()和 min()内建函数. (a) 写分别带两个元素返回一个较大和较小元素,简单的 max2()核 min2()函数.他们应该可以用任意的 pytho ...

  7. 《python核心编程第二版》第8章习题

    8–1. 条件语句. 请看下边的代码 # statement Aif x > 0:# statement Bpasselif x < 0:# statement Cpasselse:# s ...

  8. 《python核心编程第二版》第7章习题

    7–1. 字典方法.哪个字典方法可以用来把两个字典合并到一起? 答:dict1.update(dict2) 7–2. 字典的键.我们知道字典的值可以是任意的Python 对象,那字典的键又如何呢?请试 ...

  9. 《python核心编程第二版》第5章习题

    5-1 整形 讲讲 Python 普通整型和长整型的区别 答:普通整型 32位,长整数类型能表达的 数值仅仅与你的机器支持的(虚拟)内存大小有关 5-2 运算符(a) 写一个函数,计算并返回两个数的乘 ...

  10. 《python核心编程第二版》第4章习题

    4–1. Python 对象.与所有 Python 对象有关的三个属性是什么?请简单的

随机推荐

  1. [转] ReactJS之JSX语法

    JSX 语法的本质目的是为了使用基于 xml 的方式表达组件的嵌套,保持和 HTML 一致的结构,语法上除了在描述组件上比较特别以外,其它和普通的 Javascript 没有区别. 并且最终所有的 J ...

  2. POJ 1364 / HDU 3666 【差分约束-SPFA】

    POJ 1364 题解:最短路式子:d[v]<=d[u]+w 式子1:sum[a+b+1]−sum[a]>c      —      sum[a]<=sum[a+b+1]−c−1  ...

  3. 【SPFA与Dijkstra的对比】CDOJ 1961 咸鱼睡觉觉【差分约束-负权最短路径SPFA】

    差分约束系统,求最小值,跑最长路. 转自:https://www.cnblogs.com/ehanla/p/9134012.html 题解:设sum[x]为前x个咕咕中至少需要赶走的咕咕数,则sum[ ...

  4. bzoj 5099: [POI2018]Pionek

    题解: 还是比较简单的一道题 考虑现在有一个向量,当且仅当下一个向量与它夹角<90度这个向量的模长才会增加 接下来怎么做呢 如果我们去枚举初始向量,向量方向会随着新增向量而变化 随着不断顺时针的 ...

  5. A - Points and Segments CodeForces - 429E

    题解: 方法非常巧妙的一道题 首先考虑要求全部为0怎么做 发现是个欧拉回路的问题(很巧妙) 直接dfs一遍就可以了 而这道题 要求是-1,1,0 我们可以先离散化 完了之后判断每个点被奇数还是偶数条边 ...

  6. HDFS-HA高可用 | Yarn-HA

    HDFS-HA HA(High Available),即高可用(7*24小时不中断服务) 单点故障即有一台机器挂了导致全部都挂了:HA就是解决单点故障,就是针对NameNode: 主Active:读写 ...

  7. day67 ORM模型之高阶用法整理,聚合,分组查询以及F和Q用法,附练习题整理

    归纳总结的笔记: day67 ORM 特殊的语法 一个简单的语法 --翻译成--> SQL语句 语法: 1. 操作数据库表 创建表.删除表.修改表 2. 操作数据库行 增.删.改.查 怎么连数据 ...

  8. SSH框架学习------struts2前后台传值(二)

    struts2的Action类一般都会继承(extends)ActionSupport类(Action类,即实现action的类)1.前传后:jsp里<input type="text ...

  9. JDK 1.6 HashMap 源码分析

    前言 ​ 前段时间研究了一下JDK 1.6 的 HashMap 源码,把部份重要的方法分析一下,当然HashMap中还有一些值得研究得就交给读者了,如有不正确之处还望留言指正. 准备 ​ 需要熟悉数组 ...

  10. Mybatis之注解实现动态sql

    通过注解实现动态sql一共需要三部:1.创建表,2.创建entity类,3.创建mapper类, 4.创建动态sql的Provider类.1.和2.可以参见该系列其他文章,这里主要对3和4进行演示,并 ...