標籤:
原文:http://start2join.me/python-regex-answer-20141030/
###########################################
#########Exercises after Chapter 15th ##########
###########################################
相關學習書籍:《Python核心編程》第十五章——Regex習題與答案。
Regex相關知識:
章節練習題及答案:
所有程式首行加入引入re模組代碼:
import re
#15-1:識別下列字串:bat、bit、but、hat、hit、或hut。
print(‘‘‘#15-1:識別下列字串:bat、bit、but、hat、hit、或hut。‘‘‘)strList = [‘bat‘, ‘bit‘, ‘but‘, ‘hat‘, ‘hit‘, ‘hut‘]for c in strList: print (re.match(r‘[bh][aiu]t‘, c).group())
#15-2:匹配用一個空格分隔的任意一對單詞,比如名和姓。
print(‘‘‘#15-2:匹配用一個空格分隔的任意一對單詞,比如名和姓。‘‘‘)result = re.match(r‘[A-Za-z]+\s[A-Za-z]+‘, ‘Jim Green‘)print(result.group())
#15-3:匹配用一個逗號和一個空格分開的一個單詞和一個字母。例如英文人名中的姓和名的首字母。
print(‘‘‘#15-3:匹配用一個逗號和一個空格分開的一個單詞和一個字母。例如英文人名中的姓和名的首字母。‘‘‘)result = re.match(r‘([A-Za-z]\.)+?\s[A-Za-z]+‘, ‘J. Green‘)print(result.group())
#15-4:匹配所有合法的Python標識符。註:字母底線打頭,後面接任一數字字母和底線
print(‘‘‘#15-4:匹配所有合法的Python標識符。註:字母底線打頭,後面接任一數字字母和底線‘‘‘)valueList = [‘10_mys‘, ‘_myValue09‘, ‘Post99‘, ‘*hahah‘, ‘[email protected]%‘]for c in valueList: result = re.match(r‘[a-zA-Z_][\w_]+$‘, c) if result: print(c+‘:‘+result.group()) else: print(c+‘:Illegal...‘)
#15-6:匹配簡單的以www.開頭以.com結尾的web網域名稱。例如www.baidu.com。附加題:使你寫的運算式還支援其他的頂級網域名稱。如:.edu, .net等。
print(‘‘‘#15-6:匹配簡單的以www.開頭以.com結尾的web網域名稱。例如www.baidu.com。附加題:使你寫的運算式還支援其他的頂級網域名稱。如:.edu, .net等。‘‘‘)comList = [‘com‘, ‘edu‘, ‘net‘]result = re.match(r‘www.\w+.com‘, ‘www.baidu.com‘)print(result.group(0))result = re.match(r‘www[.\w]+‘, ‘www.yahoo.net‘)if result: print(result.group(0))
#15-7:匹配全體Python整形的字串表示形式的集合
print(‘‘‘#15-7:匹配全體Python整形的字串表示形式的集合‘‘‘)result = re.match(r‘\d+[Ll]?‘, ‘43545464‘)print(result.group(0))
#15-8:匹配全體Python長整形的字串表示形式的集合
print(‘‘‘#15-8:匹配全體Python長整形的字串表示形式的集合‘‘‘)result = re.match(r‘\d+[Ll]‘, ‘43545464L‘)print(result.group(0))
#15-9:匹配全體Python浮點形的字串表示形式的集合
print(‘‘‘#15-9:匹配全體Python浮點形的字串表示形式的集合‘‘‘)result = re.match(r‘\d+\.?\d+‘, ‘43545464.00001‘)print(result.group(0))
#15-10:匹配全體Python複數形的字串表示形式的集合
print(‘‘‘#15-10:匹配全體Python複數形的字串表示形式的集合‘‘‘)result = re.match(r‘\d+\.?\d+\+\d+\.?\d+j‘, ‘4.5+0.1j‘)print(result.group(0))
#15-11:匹配所有電子郵件的字串表示形式的集合
print(‘‘‘#15-11:匹配所有電子郵件的字串表示形式的集合‘‘‘)result = re.match(r‘\[email protected](\w+\.)*\w+‘, ‘[email protected]‘)print(result.group(0))
#15-12:匹配所有web網站地址的字串表示形式的集合
print(‘‘‘#15-12:匹配所有web網站地址的字串表示形式的集合‘‘‘)result = re.match(r‘\w+(\w+\.)*\w+‘, ‘www.host.cool.com‘)print(result.group(0))
#15-13:匹配標準日曆上的前9個月
print(‘‘‘#15-13:匹配標準日曆上的前9個月‘‘‘)result = re.match(r‘0?[1-9]‘, ‘07‘)print(result.group(0))
#15-14:匹配標準日曆上的後三個月
print(‘‘‘#15-14:匹配標準日曆上的後三個月‘‘‘)result = re.match(r‘1[0-2]‘, ‘11‘)print(result.group(0))
#15-15:信用卡問題:15位信用卡的格式是4-6-5。16位的信用卡格式是4-4-4-4,位元不足則添0補充。
print(‘‘‘#15-15:信用卡問題:15位信用卡的格式是4-6-5。16位的信用卡格式是4-4-4-4,位元不足則添0補充。‘‘‘)cardNo = ‘1321-1544-6511-0001‘result = re.findall(r‘(\d)‘, cardNo)if 16 == len(result): reResult = re.match(r‘[\d]{4}-[\d]{4}-[\d]{4}-[\d]{4}‘, cardNo) if reResult: print(‘It is OK!‘) else: print(‘It is Illegal...‘)elif 15 == len(result): reResult = re.match(r‘[\d]{4}-[\d]{6}-[\d]{5}‘, cardNo) if reResult: print(‘It is OK!‘) else: print(‘It is Illegal...‘)else: print(‘It is Illegal...‘)
#15-16:修改getdata.py,將產生的資料存入redate.txt中。
print(‘‘‘#15-16:修改getdata.py,將產生的資料存入redate.txt中。‘‘‘)from random import randint, choiceimport stringfrom time import ctimelowercase = []for c in ‘abcdefghijklmnopqrstuvwxyz‘: lowercase.append(c)maxint = 23554545646doms = (‘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) f.write(‘%s::%[email protected]%s.%s::%d-%d-%d\n‘ % (dtstr, em, dn, choice(doms), dtint, shorter, longer)) print(‘%s::%[email protected]%s.%s::%d-%d-%d‘ % (dtstr, em, dn, choice(doms), dtint, shorter, longer))f.close();
#15-17:統計redata.txt中各星期出現的次數。
print(‘‘‘#15-17:統計redata.txt中各星期出現的次數。‘‘‘) mon, tue, wed, thu, fri, sat, sun = 0, 0, 0, 0, 0, 0, 0 with open(‘redata.txt‘, ‘r‘) as f: for line in f: result = re.match(r‘^[\w]{3}‘, line) if result.group() == ‘Mon‘: mon += 1 elif result.group() == ‘Tue‘: tue += 1 elif result.group() == ‘Wed‘: wed += 1 elif result.group() == ‘Thu‘: thu += 1 elif result.group() == ‘Fri‘: fri += 1 elif result.group() == ‘Sat‘: sat += 1 elif result.group() == ‘Sun‘: fri += 1print(‘%s\t%s\t%s\t%s\t%s\t%s\t%s‘ % (‘mon‘, ‘tue‘, ‘wed‘, ‘thu‘, ‘fri‘, ‘sat‘, ‘sun‘))print(‘%d\t%d\t%d\t%d\t%d\t%d\t%d\n‘ % (mon, tue, wed, thu, fri, sat, sun))f.close()
#15-18:通過本文部分的整形與時間戳記進行比較,判斷檔案是否完整。
print(‘‘‘#15-18:通過本文部分的整形與時間戳記進行比較,判斷檔案是否完整。‘‘‘)with open(‘redata.txt‘, ‘r‘) as f: for line in f: timeStr = re.match(r‘.+\s\d{4}‘, line) timeInt = re.match(r‘.+::(\d+)-‘, line) if ctime(int(timeInt.group(1))) != timeStr.group(0): print(ctime(int(timeInt.group(1)))) print(‘File is Error...‘) break;
#15-19:提取每行中完整的時間戳記欄位。
print(‘‘‘#15-19:提取每行中完整的時間戳記欄位。‘‘‘)with open(‘redata.txt‘, ‘r‘) as f: for line in f: timeStr = re.match(r‘.+\s\d{4}‘, line) print(timeStr.group(0))
#15-20:提取每行中完整的電子郵件欄位。
print(‘‘‘#15-20:提取每行中完整的電子郵件欄位。‘‘‘)with open(‘redata.txt‘, ‘r‘) as f: for line in f: mailStr = re.match(r‘.+::(.+)::‘, line) print(mailStr.group(1))
#15-21:只提取每行中的月份。
print(‘‘‘#15-21:只提取每行中的月份。‘‘‘)with open(‘redata.txt‘, ‘r‘) as f: for line in f: mailStr = re.match(r‘.+\s([\w]{3})\s‘, line) print(mailStr.group(1))
#15-22:只提取每行中的年份。
print(‘‘‘#15-22:只提取每行中的年份。‘‘‘)with open(‘redata.txt‘, ‘r‘) as f: for line in f: mailStr = re.match(r‘.+\s([\w]{4})::‘, line) print(mailStr.group(1))
#15-23:只提取每行中的時間欄位(HH:MM:SS)。
print(‘‘‘#15-23:只提取每行中的時間欄位(HH:MM:SS)。‘‘‘)with open(‘redata.txt‘, ‘r‘) as f: for line in f: mailStr = re.match(r‘.+\d\s(.+)\s\d‘, line) print(mailStr.group(1))
#15-24:只提取電子郵件中登入名稱和網域名稱(串連提取).
print(‘‘‘#15-24:只提取電子郵件中登入名稱和網域名稱(串連提取).‘‘‘)with open(‘redata.txt‘, ‘r‘) as f: for line in f: mailStr = re.match(r‘.+::(.+)\.‘, line) print(mailStr.group(1))
#15-25:只提取電子郵件中登入名稱和網域名稱(分別提取)。
print(‘‘‘#15-25:只提取電子郵件中登入名稱和網域名稱(分別提取)。‘‘‘)with open(‘redata.txt‘, ‘r‘) as f: for line in f: nameStr = re.match(r‘.+::(\w+)@‘, line) zoneStr = re.match(r‘[email protected](\w+)\.‘, line) print(nameStr.group(1) + ‘-->‘ + zoneStr.group(1))
#15-26:將每行的電子郵件替換為你自己的電子郵件地址。
print(‘‘‘#15-26:將每行的電子郵件替換為你自己的電子郵件地址。‘‘‘)lines = []with open(‘redata.txt‘, ‘r‘) as r: for line in r: nameStr = re.sub(r‘\[email protected]\w+\.\w+‘, ‘[email protected]‘, line) lines.append(nameStr)with open(‘redata.txt‘, ‘w+‘) as w: for line in lines: w.write(line)with open(‘redata.txt‘, ‘r‘) as r: for line in r: print(line)
#15-27:提取出時間戳記中的月日年,並按照’月 日, 年’顯示出來(每行只遍曆一次)。
print(‘‘‘#15-27:提取出時間戳記中的月日年,並按照‘月 日, 年‘顯示出來(每行只遍曆一次)。‘‘‘)with open(‘redata.txt‘, ‘r‘) as f: for line in f: dateStr = \ re.match( r‘.+\s([\w]{3}[\s]{1,2}[\d]{1,2})\s.+\s(\d+):‘, line) print(dateStr.group(1) + ‘, ‘ + dateStr.group(2))
#15-28:提取電話號碼3-3-4,要求區號是可選的(800-555-1212和555-1212都可以匹配)。
print(‘‘‘#15-28:提取電話號碼3-3-4,要求區號是可選的。(800-555-1212和555-1212都可以匹配)。‘‘‘)numList = [‘800-555-1212‘, ‘555-1212‘]for nums in numList: number = re.match(r‘(\d{3}-)?\d{3}-\d{4}‘, nums) print(number.group())
#15-29:提取電話號碼3-3-4,要求區號可以包含園括弧或是連字號,他們是可選的(800-555-1212、555-1212或(800)555-1212都可以匹配)。
print(‘‘‘#15-29:提取電話號碼3-3-4,要求區號可以包含園括弧或是連字號,他們是可選的(800-555-1212、555-1212或(800)555-1212都可以匹配)。‘‘‘)numList = [‘800-555-1212‘, ‘555-1212‘, ‘(800)555-1212‘]for nums in numList: number = re.match(r‘(\(\d{3}\)|(\d{3}-))?\d{3}-\d{4}‘, nums) print(number.group())
Python進階編程–Regex(習題)