《python 核心編程》第15章正則表達式 答案

看了兩天正則表達式,總算是看完了也算入門了吧,順便把python 15章的習題也給一併清了。 python

如下是我的的答案,如有不當之處請指教 正則表達式

#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題在這裏 dom

#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
 



好了,總算寫完了。正則,愛你不容易啊 函數

相關文章
相關標籤/搜索