《python 核心编程》第15章正则表达式 答案

看了两天正则表达式,总算是看完了也算入门了吧,顺便把python 15章的习题也给一并清了。

以下是个人的答案,若有不当之处请指教

#coding=utf-8
#!/bin/env python
import re
#1. 识别下列字符串:“bat,” “bit,” “but,” “hat,” “hit,” 或 “hut”
def test1():
    bt='bat|bit|but|hat|hit|hut'
    inputstr=raw_input('input needs to match String')
    m=re.match(bt,inputstr)
    if m is not None:print(m.group())
    else:print 'not match'

# test1()

#2.匹配用一个空格分隔的任意一对单词,比如,名和姓
def test2():
    bt='(.*)\s(.*)'
    inputstr=raw_input('输入您的姓名,姓与名之间用空格隔开\n')
    m=re.match(bt,inputstr)
    if m is not None:
        print('您的姓是:%s'%m.group(1))
        print('您的名是:%s'%m.group(2))
        print('all is:%s'%m.group(0))
    else:print 'not match'
# test2()

#3. 匹配用一个逗号和一个空格分开的一个单词和一个字母。例如,英文人名中的姓和名 的首字母
import string
def test3():
    bt='(.*),(.*|.*\s.*)'
    inputstr=raw_input('输入您的姓名,姓与名之间用逗号隔开\n')
    m=re.match(bt,inputstr)
    if m is not None:
        print('您的姓是:%s'%m.group(1))
        print('您的名是:%s'%string.replace(m.group(2),' ',''))
        print('all is:%s'%string.replace(m.group(0),' ',''))
    else:print 'not match'
# test3()

#4. 匹配所有合法的Python标识符


def test4():
    role='\w.*'
    inputstr=raw_input('输入待检测的string 是否是标示符\n')
    m=re.match(role,inputstr)
    if m is not None:
        print("%s是一个合格的标示符"%m.group())
    else:
        print '%s不是一个合格的标示符'%inputstr
# test4()

#5.请根据您(读者)本地关于地址的格式写法匹配一个街道地址(你写出的正则表达式要 尽可能通用以匹配任意数目的表示街道名字的单词,包括类型指示)。比如,美国的街道地址使用这 样的格式:1180 Bordeaux Drive.使你写的正则表达式尽可能通用,要求能够匹配多个单词的街道 名字,如:3120 De la Cruz Boulevard.
def test5():
    role='(\d+\s?)+(\S+\s?)+'
    inputstr=raw_input('输入待检测的string 是否是标示符\n')
    m=re.match(role,inputstr)
    if m is not None:
        print("%s是一个街道名"%m.group())
    else:
        print '%s不是一个街道名'%inputstr

# test5()


#6.匹配简单的以“www.”开头,以“.com”作结尾的Web域名,例如:www.yahoo.com.
def test6():

    role='(^www)\.(\S+)\.?([com|end|cn|net])'
    inputstr=raw_input('输入需要检测的网址\n')
    m=re.match(role,inputstr)
    if m is not None:
        print("%s是一个网址"%m.group())
    else:
        print '%s不是一合格的网址'%inputstr
# test6()

#7.匹配全体Python整数的字符串表示形式的集合
#8. 匹配全体Python长整数的字符串表示形式的集合
#9. 匹配全体Python浮点数的字符串表示形式的集合
#10.匹配全体Python复数的字符串表示形式的集合

def test7_10():
    role7='\d+'
    role8='\d+[L]?'
    role9='\d+.\d+'
    role10='\d'
    inputstr7=raw_input('输入需要检测的整形数字\n')
    inputstr8=raw_input('输入需要检测的长整形数字\n')
    inputstr9=raw_input('输入需要检测的浮点数字\n')
    inputstr10=raw_input('输入需要检测的复数\n')
    m7=re.match(role7,inputstr7)
    m8=re.match(role8,inputstr8)
    m9=re.match(role9,inputstr9)
    m10=re.match(role10,inputstr10)
    if m7 is not None:
        print ('整形:%s'%m7.group())
    if m8 is not None:
        print ('长整形:%s'%m8.group())
    if m9 is not None:
        print ('浮点数:%s'%m9.group())
    if m10 is not None:
        print ('复数:%s'%m10.group())
# test7_10()

#11.匹配所有合法的电子邮件地址(先写出一个限制比较宽松的正则表达式,然后尽可能加 强限制条件,但要保证功能的正确性)。
def test11():
    role="[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?"
    inputstr=raw_input('输入需要检测的邮箱\n')
    m=re.match(role,inputstr);
    if m is not None:
        print'email is :%s'%m.group()
    else:
        print 'not a email'
# test11()

#12.匹配所有合法的 Web 网站地址(URLs)(先写出一个限制比较宽松的正则表达式,然后尽可能加强限制条件,但要保证功能的正确性)。
def test12():
    role="[a-zA-z]+://[^\s]*"
    inputstr=raw_input('输入需要检测的URL\n')
    m=re.match(role,inputstr);
    if m is not None:
        print'URL is :%s'%m.group()
    else:
        print 'not a URL'
# test12()


#13.type(). type()内建函数返回一个对象类型,此对象显示为 Python 的字符串形式
def test13():
    import re
    data="<type 'int'>"
    patt="<type\s'(\w+)'>"
    m=re.search(patt, data)
    if m is not None:
        print m.group(1)
# test13()


#14.正则表达式。在 15.2 小节里,我们给出一个匹配由一位或两位数字代表一月到九月的 字符串形式(“0?[1-9]”)。 请写出一个正则表达式    表示标准日历上其它的三个月(十月、十一月、 十二月)。
def test14():
    role="1[0-2]"
    m=re.match(role,'10')
    print m.group()
# test14()


#15.正则表达式。在15.2小节里,我们给出一个匹配信用卡卡号的模式:(“[0-9]{15,16}”).  但这个模式不允许用连字符号分割信用卡卡号中的数字。请写出一个允许使用连字符的正则表达式, 但要求连字符必须出现在正确的位置。例如,15位的信用卡卡号的格式是4-6-5,表示四个数字,一 个连字符,后面接六个数字、一个连字符,最后是五个数字。16位的信用卡卡号的格式是4-4-4-4, 数位不足时,添0补位。
def test15():
    role='([0-9]{4}-?[0-9]{6}-?[0-9]{5})|([0-9]{4}-?[0-9]{4}-?[0-9]{4}-[0-9]{4})'
    inputstr=raw_input('输入需要检测的信用卡号\n')
    m=re.match(role,inputstr);
    if m is not None:
        print'right :%s'%m.group()
    else:
        print 'not a card Number'
# test15()


#17.统计生成的redata.txt文件中,星期中的每一天出现的次数(或统计各月份出现的次 数)。
#18.通过检查每个输出行中整数字段部分的第一个整数是否和该行开头的时间戳相匹配来 验证redata.txt中的数据是否完好
#19. 提取出每行中完整的时间戳字段
#20.提取出每行中完整的电子邮件地址。
#21.只提取出时间戳字段中的月份。
#22.只提取出时间戳字段中的年份
#23.只提取出时间戳字段中的值(格式:HH:MM:SS)。
#24.只从电子邮件地址中提取出登录名和域名(包括主域名和顶级域名,二者连在一起)
#25.只从电子邮件地址中提取出登录名和域名(包括主域名和顶级域名,二者分别提取)。
def test17_25():
    role17='Jun'
    role19="\s(\d{1,2}):(\d{1,2}):(\d{1,2})\s"
    role20="[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?"
    role21="\s\w+\s"
    role22="\s[0-9]{4}"
    role23=""#和19有什么区别?
    role24="(\w+)@(\w+).(\w+)"
    role25="(\w+)@(\w+).(\w+)"
    f=open('redata.txt','r')
    count=0
    for eachLine in f.readlines():
        m=re.findall(role17, eachLine)
        count+=len(m)


        strTemp=str(eachLine)

        m19=re.search(role19,strTemp)
        print'19_______'
        print m19.group()

        m20=re.search(role20,strTemp)
        print'20_______'
        print m20.group()


        m21=re.search(role21,strTemp)
        print'21_______'
        print m21.group()

        m22=re.search(role22,strTemp)
        print'22_______'
        print m22.group()

        m24=re.search(role24,strTemp)
        m24temp=re.split('@',m24.group())
        m24real=m24temp[0]+m24temp[1]
        print'24_______'
        print m24real

    print 'the count of :%s is %d' %(role17,count)
    f.close()
# test17_25()

#26. 将每行中的电子邮件地址替换为你自己的电子邮件地址
def test26():
    role26="[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?"
    f=open('redata.txt','r')
    files=f.readlines()
    for eachfile in files:
        m26=re.search(role26,str(eachfile))
        print m26.group()
        m26_my=re.sub(role26,'swrite.126.com',str(eachfile))
        print m26_my


# test26()
#27.提取出时间戳中的月、日、年,并按照格式“月 日,年”显示出来,且每行仅遍 历一次
def test27():
    role="(\S+)\s(\d+)\s\d+:\d+:\d+\s(\d+)"
    f=open('redata.txt','r')
    files=f.readlines()
    for eachfile in files:
        m27=re.search(role,str(eachfile))
        try:
            print "%s-%s-%s" %(m27.group(1),m27.group(2),m27.group(3))
        except(AttributeError),djag:
            pass

# test27()

#28.区号(第一组的三个数字和它后面的连字符)是可选的,即,你写的正则表达式对 800-555-1212和555-1212都可以匹配
def test28():
    role="(\d{3}-)?\d{3}-\d{4}"
    m=re.match(role,'800-555-1212')
    print m.group()
    m2=re.match(role,'555-1212')
    print m2.group()
# test28()


#29.区号中可以包含圆括号或是连字符,而且它们是可选的,就是说你写的正则表达式可以 匹配800-555-1212, 或 555-1212, 或(800) 555-1212
def test29():
    role="\(?\d{3}\)?-?\d{3}-\d{4}" #目前第二条没匹配到555-1212
    m=re.match(role,'800-555-1212')
    print m.group()
    m2=re.match(role,'555-1212')
    if m2 is not None:
        print m2.group()
    else:
        print 'm2 not match'

    m3=re.match(role,'(800)555-1212')
    print m3.group()
test29()

第16题在这里

#coding=utf-8
#!/bin/env python
#16.修改脚本 gendata.py 的代码,使数据直接写入文件 redata.txt 中,而不是输出到屏 幕上。
from random import  randint,choice
from string import  lowercase
from sys import  maxint
from time import  ctime

doms=('com','edu','net','org','gov')

for i in range(randint(5,10)):
    dtint=randint(0,maxint-1)
    # print(dtint)
    dtstr=ctime(dtint)
    # print(dtstr)
    shorter=randint(4,7)
    # print(shorter)
    # print'_'*10
    em=''
    for j in range(shorter):
        em+=choice(lowercase)
        # print(em)
    # print '-'*10
    longer=randint(shorter,12)
    # print(longer)
    dn=''
    # print '-'*10
    for j in range(longer):
        dn+=choice(lowercase)
        # print(dn)

    str='%s::%s@%s.%s::%d-%d-%d'%(dtstr,em,dn,choice(doms),dtint,shorter,longer)
    file=open('redata.txt','a')
    #重定向输出到file
    print >>file,str
 



好了,总算写完了。正则,爱你不容易啊

你可能感兴趣的:(《python 核心编程》第15章正则表达式 答案)