今日學習內容總結1.9
今日內容學習總結
通過上週的學習,我們對於模組的運用有了一個瞭解,這周開始我們以一個正則表示式開始進行學習。
正則表示式簡介
正則表示式,是一門獨特的語言,專門用來匹配,校驗,篩查所需的資料。同時正則表示式是一個特殊的字元序列,它能幫助你方便的檢查一個字串是否與某種模式匹配。它可以利用一些特殊符號的組合去字串中篩選出想要的資料。所以我們學習正則表示式,很大程度上就是學習一些特殊符號的使用。
Python 自1.5版本起增加了re 模組,它提供 Perl 風格的正則表示式模式。re 模組使 Python 語言擁有全部的正則表示式功能。這裡我們用一個案例來實現正則表示式:
# 有些網站獲取手機號會有很多校驗規則,我們通過程式碼實現這些功能 # 1.獲取使用者的手機號 phone_num = input('請輸入您的手機號>>>:').strip() # 2.先校驗是否是11位 if len(phone_num) == 11: # 3.再校驗是否是純數字 if phone_num.isdigit(): # 4.校驗開頭是否合法 if phone_num.startswith('13') or phone_num.startswith('15') or phone_num.startswith( '17') or phone_num.startswith('18'): print('是一個正確的手機號') else: print('手機號開頭不合法') else: print('手機號必須是純數字') else: print('手機號必須是11位')
上述程式碼我們通過不斷的if是實現了這個校驗的效果,現在我們看看如果通過正則表示式實現會怎麼樣:
# 正則表示式實現手機校驗功能
import re
phone_number = input('請輸入你的手機號: ').strip()
if re.match('^(13|14|15|18)[0-9]{9}$', phone_number):
print('是正確的手機號碼')
else:
print('手機號碼格式不正確')
我們發現,正則表示式也是一個簡化程式碼,提高程式碼效率的功能。而我們使用正則表示式,是因為典型的搜尋和替換操作要求您提供與預期的搜尋結果匹配的確切文字。雖然這種技術對於對靜態文字執行簡單搜尋和替換任務可能已經足夠了,但它缺乏靈活性,若採用這種方法搜尋動態文字,即使不是不可能,至少也會變得很困難。但是正則表示式擁有一下三個優點:1.測試字串內的模式。2.替換文字。3.基於模式匹配從字串中提取子字串。
在匹配篩選查詢資料的時候可以使用正則提供的符號也可以直接寫目標資料。
正則表示式之字元組
例項 | 描述 |
---|---|
[Pp]ython | 匹配 "Python" 或 "python" |
rub[ye] | 匹配 "ruby" 或 "rube" |
[aeiou] | 匹配中括號內的任意一個字母 |
[0-9] | 匹配任何數字。類似於 [0123456789] |
[a-z] | 匹配任何小寫字母 |
[A-Z] | 匹配任何大寫字母 |
[a-zA-Z0-9] | 匹配任何字母及數字(順序可變如[A-Z0-9a-z]) |
[^aeiou] | 除了aeiou字母以外的所有字元 |
[^0-9] | 匹配除了數字外的字元 |
正則表示式之特殊字元
例項 | 描述 |
---|---|
. | 匹配除 "\n" 之外的任何單個字元。要匹配包括 '\n' 在內的任何字元,請使用象 '[.\n]' 的模式。 |
\d | 匹配一個數字字元。等價於 [0-9]。 |
\D | 匹配一個非數字字元。等價於 [^0-9]。 |
$ | 匹配字串的結尾 |
\S | 匹配任何非空白字元。等價於 [^ \f\n\r\t\v]。 |
\w | 匹配包括下劃線的任何單詞字元。等價於'[A-Za-z0-9_]'。 |
\W | 匹配任何非單詞字元。等價於 '[^A-Za-z0-9_]'。 |
^ | 匹配字串的開頭 |
\n, \t, 等. | 匹配一個換行符。匹配一個製表符。等 |
() | 給正則表示式分組 不影響正則匹配 |
[] | 字元組的概念(裡面所有的資料都是或的關係) |
[^] | 上箭號出現在了中括號的裡面意思是取反操作 |
正則表示式之量詞
例項 | 描述 |
---|---|
* | 重複零次或者多次(預設就是多次:越多越好) |
+ | 重複一次或者多次(預設就是多次:越多越好) |
? | 重複零次或者一次(預設就是一次:越多越好) |
{n} | 重複n次 |
{n,} | 重複最少n次最多多次(越多越好) |
{n,m} | 重複n到m次(越多越好) |
複雜的正則編寫
很多常見的正則校驗符號,不需要我們編寫,直接百度查詢即可。程式碼示例:
# 校驗使用者身份證號碼15位或者17位
^[1-9][0-9]{14} # 校驗15位
^[1-9][0-9]{16}[0-9x] # 校驗17位,同時末位可能是數字或x
取消轉義
\n \n False
\\n \n True
\\\\n \\n True
# 在python中還可以在字串的前面加r取消轉義
貪婪匹配與非貪婪匹配
貪婪與非貪婪模式影響的是被量詞修飾的子表示式的匹配行為,貪婪模式在整個表示式匹配成功的前提下,儘可能多的匹配,而非貪婪模式在整個表示式匹配成功的前提下,儘可能少的匹配。程式碼示例:
<.*> <script>alert(123)<script> # 1條
<.*?> <script>alert(123)<script> # 2條
re 模組
在python中無法直接使用正則,需要藉助於模組。而藉助的模組就是re模組。re模組是python獨有的匹配字串的模組,該模組中提供的很多功能是基於正則表示式實現的。
常用方法
1.re.compile(pattern,flags = 0 )
將正則表示式模式編譯為正則表示式物件,可使用match(),search()以及下面所述的其他方法將其用於匹配
import re
a = re.compile('\d{2}')
print(a.search('12abc')) # <_sre.SRE_Match object; span=(0, 2), match='12'>
print(a.search('12abc').group()) # 12 通過呼叫group()方法得到匹配的字串,如果字串沒有匹配,則返回None。
2、re.search(pattern,string,flags = 0 )
掃描字串以查詢正則表示式模式產生匹配項的第一個位置 ,然後返回相應的match物件。None如果字串中沒有位置與模式匹配,則返回;否則返回false。請注意,這與在字串中的某個點找到零長度匹配不同。
import re
# 在這個字串進行匹配,只會匹配一個物件
print(re.search('\w+', 'abcde').group()) # abcde
print(re.search('a', 'abcde').group()) # a
3、re.match(pattern,string,flags = 0 )
如果字串開頭的零個或多個字元與正則表示式模式匹配,則返回相應的匹配物件。None如果字串與模式不匹配,則返回;否則返回false。請注意,這與零長度匹配不同。
import re
# 同search,不過在字串開始處進行匹配,只會匹配一個物件
print(re.match('\w+', 'abc123de').group()) # abc123de
print(re.match('a', 'abcde').group()) # a
print(re.match('\D+', 'abc123de').group()) # abc
4、re.fullmatch(pattern,string,flags = 0 )
如果整個字串與正則表示式模式匹配,則返回相應的match物件。None如果字串與模式不匹配,則返回;否則返回false。請注意,這與零長度匹配不同。
import re
print(re.fullmatch('\w+', 'abcde').group()) # abcde
print(re.fullmatch('abcde', 'abcde').group()) # abcde
5、re.split(pattern,string,maxsplit = 0,flags = 0 )
通過出現模式來拆分字串。如果在pattern中使用了捕獲括號,那麼模式中所有組的文字也將作為結果列表的一部分返回。如果maxsplit不為零,則最多會發生maxsplit分割,並將字串的其餘部分作為列表的最後一個元素返回。
import re
print(re.split('[ab]', 'abcde')) # ['', '', 'cde'] 先按'a'分割得到''和'bcd',在對''和'bcd'分別按'b'分割
print(re.split(r'\W+', 'Words, words, words.')) # ['Words', 'words', 'words', '']
print(re.split(r'(\W+)', 'Words, words, words.', 1)) # ['Words', ', ', 'words, words.']
print(re.split(r'(\W+)', 'Words, words, words.')) # ['Words', ', ', 'words', ', ', 'words', '.', '']
print(re.split('[a-f]+', '0a3d9g1d', flags=re.IGNORECASE)) # ['0', '3', '9g1', '']
6、re.findall(pattern,string,flags = 0 )
以string列表形式返回string中pattern的所有非重疊匹配項。從左到右掃描該字串,並以找到的順序返回匹配項。如果該模式中存在一個或多個組,則返回一個組列表;否則,返回一個列表。如果模式包含多個組,則這將是一個元組列表。空匹配項包含在結果中。
import re
pprint(re.findall('a', 'This is a beautiful place!')) # ['a', 'a', 'a']
7、re.finditer(pattern,string,flags = 0 )
返回一個迭代器,該迭代器在string型別的RE 模式的所有非重疊匹配中產生匹配物件。 從左到右掃描該字串,並以找到的順序返回匹配項。空匹配項包含在結果中。
import re
print(re.finditer('[ab]', 'This is a beautiful place!')) # <callable_iterator object at 0x000001E6AA03E278> 迭代器物件
res = re.finditer('[ab]', 'This is a beautiful place!')
print(next(res).group()) # a
res_list = [i.group() for i in res]
print(res_list) # ['b', 'a', 'a']
8、re.sub(pattern,repl,string,count = 0,flags = 0 )
返回通過用替換repl替換字串中最左邊的不重疊模式所獲得的字串。如果找不到該模式, 則返回的字串不變。 repl可以是字串或函式;如果是字串,則處理其中的任何反斜槓轉義。即,將其轉換為單個換行符,將其轉換為回車,依此類推。count引數表示將匹配到的內容進行替換的次數
import re
print(re.sub('\d', 's', 'abc12jh45li78', 2)) # abcssjh45li78 將匹配到的數字替換成S,替換2個 不寫2預設情況是將匹配到所有的數字替換成S
9、re.subn(pattern,repl,string,count = 0,flags = 0 )
執行與相同的操作sub(),但返回一個元組。(new_string, number_of_subs_made)
import re
print(re.subn('\d', 's', 'abc12jh45li78', 3)) # ('abcssjhs5li78', 3)
10、re.escape(pattern)
escape中的所有字元圖案,除了ASCII字母,數字和'_'。如果要匹配可能包含正則表示式元字元的任意文字字串。
import re
print(re.escape('python.exe\n')) # python\.exe\
11、search()與match()方法
Python提供了兩種基於正則表示式的原始操作: re.match()僅在字串的開頭匹配,re.search()檢查匹配項,在字串中的任何位置檢查匹配項(這是Perl的預設設定)。
import re
print(re.match("c", "abcdef")) # None
print(re.search("c", "abcdef")) # <_sre.SRE_Match object; span=(2, 3), match='c'>
# 以開頭的正則表示式'^'可用於search()限制字串開頭的匹配項
print(re.match("c", "abcdef")) # None
print(re.match("^c", "abcdef")) # None
print(re.match("^a", "abcdef")) # <_sre.SRE_Match object; span=(0, 1), match='a'>