python re模块_python 正则表达式 (重点) re模块
京東的注冊頁面,打開頁面我們就看到這些要求輸入個人信息的提示。
假如我們隨意的在手機號碼這一欄輸入一個11111111111,它會提示我們格式有誤。
這個功能是怎么實現的呢?
假如現在你用python寫一段代碼,類似:
phone_number = input('please input your phone number :')
你怎么判斷這個phone_number是合法的呢?
根據手機號碼一共11位并且是只以13、14、15、18開頭的數字這些特點,我們用python寫了如下代碼:
whileTrue:
phone_number= input('please input your phone number :')if len(phone_number) == 11\andphone_number.isdigit()\and (phone_number.startswith('13') \or phone_number.startswith('14') \or phone_number.startswith('15') \or phone_number.startswith('18')):print('是合法的手機號碼')else:print('不是合法的手機號碼')
low版
importre
phone_number= input('please input your phone number :')if re.match('^(13|14|15|18)[0-9]{9}$',phone_number):print('是合法的手機號碼')else:print('不是合法的手機號碼')
正則版
對比上面的兩種寫法,此時此刻,我要問你你喜歡哪種方法呀?你肯定還是會說第一種,為什么呢?因為第一種不用學呀!
但是如果現在有一個文件,我讓你從整個文件里匹配出所有的手機號碼。你用python給我寫個試試?
但是學了今天的技能之后,分分鐘幫你搞定!
今天我們要學習python里的re模塊和正則表達式,學會了這個就可以幫我們解決剛剛的疑問。正則表達式不僅在python領域,在整個編程屆都占有舉足輕重的地位。
不管以后你是不是去做python開發,只要你是一個程序員就應該了解正則表達式的基本使用。如果未來你要在爬蟲領域發展,你就更應該好好學習這方面的知識。
但是你要知道,re模塊本質上和正則表達式沒有一毛錢的關系。re模塊和正則表達式的關系 類似于 time模塊和時間的關系
你沒有學習python之前,也不知道有一個time模塊,但是你已經認識時間了12:30就表示中午十二點半(這個時間可好,一般這會兒就該下課了)。
時間有自己的格式,年月日時分秒,12個月,365天......已經成為了一種規則。你也早就牢記于心了。time模塊只不過是python提供給我們的可以方便我們操作時間的一個工具而已
正則表達式本身也和python沒有什么關系,就是匹配字符串內容的一種規則。
官方定義:正則表達式是對字符串操作的一種邏輯公式,就是用事先定義好的一些特定字符、及這些特定字符的組合,組成一個“規則字符串”,
這個“規則字符串”用來表達對字符串的一種過濾邏輯。
正則表達式
一說規則我已經知道你很暈了,現在就讓我們先來看一些實際的應用。
首先你要知道的是,談到正則,就只和字符串相關了。在我給你提供的工具中,你輸入的每一個字都是一個字符串。
其次,如果在一個位置的一個值,不會出現什么變化,那么是不需要規則的。
比如你要用"1"去匹配"1",或者用"2"去匹配"2",直接就可以匹配上。這連python的字符串操作都可以輕松做到。
那么在之后我們更多要考慮的是在同一個位置上可以出現的字符的范圍。
字符組 : [字符組]
在同一個位置可能出現的各種字符組成了一個字符組,在正則表達式中用[]表示
字符分為很多類,比如數字、字母、標點等等。
假如你現在要求一個位置"只能出現一個數字",那么這個位置上的字符只能是0、1、2...9這10個數之一。
字符組
正則
待匹配字符
匹配
結果
說明
[0123456789]
8
True
在一個字符組里枚舉合法的所有字符,字符組里的任意一個字符
和"待匹配字符"相同都視為可以匹配
[0123456789]
a
False
由于字符組中沒有"a"字符,所以不能匹配
[0-9]
7
True
也可以用-表示范圍,[0-9]就和[0123456789]是一個意思
[a-z]
s
True
同樣的如果要匹配所有的小寫字母,直接用[a-z]就可以表示
[A-Z]
B
True
[A-Z]就表示所有的大寫字母
[0-9a-fA-F]
e
True
可以匹配數字,大小寫形式的a~f,用來驗證十六進制字符
字符:
元字符
匹配內容
.
匹配除換行符以外的任意字符
\w
匹配字母或數字或下劃線
\s
匹配任意的空白符
\d
匹配數字
\n
匹配一個換行符
\t
匹配一個制表符
\b
匹配一個單詞的結尾
^
匹配字符串的開始
$
匹配字符串的結尾
\W
匹配非字母或數字或下劃線
\D
匹配非數字
\S
匹配非空白符
a|b
匹配字符a或字符b
()
匹配括號內的表達式,也表示一個組
[...]
匹配字符組中的字符
[^...]
匹配除了字符組中字符的所有字符
re模塊下的常用方法
ret = re.findall('\d+','kjasdgk912798jkshf912847jzhsfk91278')print(ret)#一次性返回所有匹配到的項,直接存在列表中
importre#ret = re.findall('\d+(?:\.\d+)?','1.2345+4.3')#?:寫在一個分組的最開始,表示在findall方法中取消這個分組的優先級#1.2345 4.3#.2345 .3#print(ret)
例子2:#ret = re.findall('www.(?:baidu|oldboy).com', 'www.oldboy.com')#print(ret) 加上?:打印全部,不加打印oldboy
findall
注意:
1 findall的優先級查詢:
import re
ret = re.findall('www.(baidu|oldboy).com', 'www.oldboy.com')
print(ret) # ['oldboy'] 這是因為findall會優先把匹配結果組里內容返回,如果想要匹配結果,取消權限即可
ret = re.findall('www.(?:baidu|oldboy).com', 'www.oldboy.com')
print(ret) # ['www.oldboy.com']
ret = re.search('a', 'eva egon yuan').group()print(ret) #結果 : 'a'#函數會在字符串內查找模式匹配,只到找到第一個匹配然后返回一個包含匹配信息的對象,該對象可以#通過調用group()方法得到匹配的字符串,如果字符串沒有匹配,則返回None。
search
注意:
s="2.22*33"
m=re.search("(\d+\.\d+)([*])(\d+)",s)
print(m.group(0)) 2.22*33
print(m.group(1)) 2.22
print(m.group(2)) *
print(m.group(3)) 33
ret = re.match('a', 'abc').group() #同search,不過只在字符串開始處進行匹配
print(ret)#結果 : 'a'
match
ret = re.split('[ab]', 'abcd') #先按'a'分割得到''和'bcd',在對''和'bcd'分別按'b'分割
print(ret) #['', '', 'cd']
#split中如果帶有分組,會在分割的同時保留被分割內容中帶分組的部分#ret = re.split('(\d\d)','alex83wusir38egon20')#print(ret) ['alex', '83', 'wusir', '38', 'egon', '20', '']
split
ret = re.sub('\d', 'H', 'eva3egon4yuan4', 1)#將數字替換成'H',參數1表示只替換1個
print(ret) #evaHegon4yuan4
sub
ret = re.subn('\d', 'H', 'eva3egon4yuan4')#將數字替換成'H',返回元組(替換的結果,替換了多少次)
print(ret) ('evaHegonHyuanH', 3)
subn
obj = re.compile('\d{3}') #將正則表達式編譯成為一個 正則表達式對象,規則要匹配的是3個數字
ret = obj.search('abc123eeee') #正則表達式對象調用search,參數為待匹配的字符串
print(ret.group()) #結果 : 123
compile
ret = re.finditer('\d', 'ds3sy4784a') #finditer返回一個存放匹配結果的迭代器
print(ret) #
print(next(ret).group()) #查看第一個結果
print(next(ret).group()) #查看第二個結果
print([i.group() for i in ret]) #查看剩余的左右結果
finditer
綜合練習與擴展
importre
ret= re.search("<(?P\w+)>\w+(?P=tag_name)>","
hello
")#還可以在分組中利用?的形式給分組起名字#獲取的匹配結果可以直接用group('名字')拿到對應的值print(ret.group('tag_name')) #結果 :h1
print(ret.group()) #結果 :
hello
ret= re.search(r"<(\w+)>\w+\1>","
hello
")#如果不給組起名字,也可以用\序號來找到對應的組,表示要找的內容和前面的組內容一致#獲取的匹配結果可以直接用group(序號)拿到對應的值print(ret.group(1))print(ret.group()) #結果 :
hello
匹配標簽
importre
ret=re.findall(r"\d+","1-2*(60+(-40.35/5)-(-4*3))")print(ret) #['1', '2', '60', '40', '35', '5', '4', '3']
ret=re.findall(r"-?\d+\.\d*|(-?\d+)","1-2*(60+(-40.35/5)-(-4*3))")print(ret) #['1', '-2', '60', '', '5', '-4', '3']
ret.remove("")print(ret) #['1', '-2', '60', '5', '-4', '3']
匹配整數
1、 匹配一段文本中的每行的郵箱
http://blog.csdn.net/make164492212/article/details/51656638
2、 匹配一段文本中的每行的時間字符串,比如:‘1990-07-12’;
分別取出1年的12個月(^(0?[1-9]|1[0-2])$)、
一個月的31天:^((0?[1-9])|((1|2)[0-9])|30|31)$3、 匹配qq號。(騰訊QQ號從10000開始) [1,9][0,9]{4,}4、 匹配一個浮點數。 ^(-?\d+)(\.\d+)?$ 或者 -?\d+\.?\d*
5、 匹配漢字。 ^[\u4e00-\u9fa5]{0,}$6、 匹配出所有整數
數字匹配
importrequestsimportreimportjsondefgetPage(url):
response=requests.get(url)returnresponse.textdefparsePage(s):
com=re.compile('
.*? .*? (?P\d+).*?(?P.*?)''.*?.*?(?P.*?)評價',re.S)
ret=com.finditer(s)for i inret:yield{"id":i.group("id"),"title":i.group("title"),"rating_num":i.group("rating_num"),"comment_num":i.group("comment_num"),
}defmain(num):
url='https://movie.douban.com/top250?start=%s&filter='%num
response_html=getPage(url)
ret=parsePage(response_html)print(ret)
f=open("move_info7","a",encoding="utf8")for obj inret:print(obj)
data=json.dumps(obj,ensure_ascii=False)
f.write(data+"\n")if __name__ == '__main__':
count=0for i in range(10):
main(count)
count+=25
爬蟲練習簡單版
importreimportjsonfrom urllib.request importurlopendefgetPage(url):
response=urlopen(url)return response.read().decode('utf-8')defparsePage(s):
com=re.compile('
.*? .*?(?P\d+).*?(?P.*?)''.*?.*?(?P.*?)評價', re.S)
ret=com.finditer(s)for i inret:yield{"id": i.group("id"),"title": i.group("title"),"rating_num": i.group("rating_num"),"comment_num": i.group("comment_num"),
}defmain(num):
url= 'https://movie.douban.com/top250?start=%s&filter=' %num
response_html=getPage(url)
ret=parsePage(response_html)print(ret)
f= open("move_info7", "a", encoding="utf8")for obj inret:print(obj)
data=str(obj)
f.write(data+ "\n")
count=0for i in range(10):
main(count)
count+= 25
爬蟲練習高級版
flags有很多可選值:
re.I(IGNORECASE)忽略大小寫,括號內是完整的寫法
re.M(MULTILINE)多行模式,改變^和$的行為
re.S(DOTALL)點可以匹配任意字符,包括換行符
re.L(LOCALE)做本地化識別的匹配,表示特殊字符集 \w, \W, \b, \B, \s, \S 依賴于當前環境,不推薦使用
re.U(UNICODE) 使用\w \W \s \S \d \D使用取決于unicode定義的字符屬性。在python3中默認使用該flag
re.X(VERBOSE)冗長模式,該模式下pattern字符串可以是多行的,忽略空白字符,并可以添加注釋
flags
總結
以上是生活随笔為你收集整理的python re模块_python 正则表达式 (重点) re模块的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2019.11.4 英语学习
- 下一篇: websocket python爬虫_p