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) 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) if m is not None: print m.group() else: print 'not match'15-4.匹配所有合法的python标识符。
from re import match ident = raw_input('input: ') m = match('^[_a-zA-Z][_\w]*',ident) if m is not None: print m.group() else: print 'not match'15-6.匹配简单的以www.开头,以.com结尾的web域名。
from re import match web = raw_input('input: ') m = match('^www\..+\.com$',web) if m is not None: print m.group() else: print 'not match'15-7.匹配全体Python整型的字符串表示形式的集合。
from re import match num = raw_input('input: ') m = match('[\da-fA-F]+',num) if m is not None: print m.group() else: print 'not match'15-9.匹配全体Python浮点型的字符串表示的集合。
from re import match num = raw_input('input: ') m = match('\d*(\.)?(\d+([eE]?[+-]?\d+)?)?',num) if m is not None: print m.group() else: print 'not match'15-10.匹配全体Python复数的字符串表示形式的集合。
from re import match num = raw_input('input: ') m = match('(?P<num>\d*(\.)?(\d+([eE]?[+-]?\d+)?)?)+(?P=num)j',num) if m is not None: print m.group() else: print 'not match'15-11.匹配所有的合法电子邮件地址。
from re import match email = raw_input('input: ') m = match('\w+@\w+(\.com|\.edu|\.gov)',email) if m is not None: print m.group() else: print 'not match'15-12.匹配所有合法的Web网站地址。
from re import match addr = raw_input('input: ') m = match('\w+\..+',addr) if m is not None: print m.group() else: print 'not match'15-13.写一个正则表达式,能从type()返回的字符串中提取类型的名字。
from re import match ret = type(.34) m = match("<type '(\w+)'>",str(ret)) if m is not None: print m.group(1)15-14.请写出一个正则表达式表示标准日历上的月份。
from re import match for month in range(20): m = match("^(0?[1-9])$|^(10|11|12)$",str(month)) if m is not None: print m.group()15-15.在15.2小节里,我们给出一个匹配信用卡卡号的模式:[0-9]{15,16}。但这个模式不允许用连字符号分割卡号中的数字。请写出一个允许使用连字符的正则表达式,但要求连字符必须出现在正确的位置。例如,15位卡号的格式是4-6-5,16位卡号的格式是4-4-4-4,位数不足时,添0补位。
from re import match card = raw_input('card: ') m = match('(\d{4}-\d{4}-\d{4}-\d{4})|(\d{4}-\d{6}-\d{5})',card) if m is not None: print m.group()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 week15-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-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.只提取时间戳中的时间。
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-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.区号(第一组的三个数字和它后面的连字符)是可选的,即你写的正则表达式对800-555-1212和555-1212都可匹配。
import re tel = raw_input('Phone: ') m = re.match('(\d{3}-)*\d{3}-\d{4}',tel) if m is not None: print m.group() else: print 'Not match'15-29.区号中可以包含圆括号或连字符,而且它们是可选的,就是说你写的正则表达式可以匹配800-555-1212、555-1212或(800)555-1212。
import re tel = raw_input('Phone: ') m = re.match('(\d{3}-|\(\d{3}\))*\d{3}-\d{4}',tel) if m is not None: print m.group() else: print 'Not match'