正則表達式是匹配字符串的強大工具, 在每一個編程語言中都有正則表達式的概念, 利用正則表達式, 咱們從返回的頁面內容中提取想要的內容就變的比較方便了python
模式 | 描述 |
---|---|
\w | 匹配字母數字及下劃線 |
\W | 匹配非字母數字下劃線 |
\s | 匹配任意空白字符,等價於[\t,\n,\r,\f] |
\S | 匹配任意非空字符 |
\d | 匹配任意數字,等價於[0-9] |
\D | 匹配任意非數字 |
\A | 匹配以xx字符串開始 |
\Z | 匹配xx字符串結束,若是是存在換行,只匹配到換行前的結束字符串 |
\z | 匹配xx字符串結束 |
\G | 匹配最後匹配完成的位置 |
\n | 匹配一個換行符 |
\t | 匹配一個製表符 |
^ | 匹配字符串的開頭 |
$ | 匹配字符串的末尾 |
. | 匹配任意字符, 除了換行符, 當 re.DOTALL 標記被指定時, 則能夠匹配包括換行符的任意字符 |
[...] | 用來表示一組字符, 單獨列出:[amk] 匹配 'a','m' 或 'k' |
[^...] | 不在 [ ] 中的字符:[^abc] 匹配除了a, b, c以外的字符 |
* | 匹配0個或多個的表達式 |
+ | 匹配1個或多個的表達式 |
? | 匹配0個或1個由前面的正則表達式定義的片斷,非貪婪方式 |
{n} | 精確匹配n個前面表達式。 |
{n,m} | 匹配n到m次由前面的正則表達式定義的片斷,貪婪方式 |
alb | 匹配a或b |
() | 匹配括號內的表達式,也表示一個組 |
ps : [...]
講解 : [ ]
全部的特殊字符在字符集中都失去其原有的特殊含義,在字符集中若是要使用]
、-
或^
,能夠在前面加上反斜槓,或把]
、-
放在第一個字符,把^
放在非第一個字符正則表達式
更多正則表達式 : https://www.jb51.net/tools/regexsc.htm編程
正則表達式就是由一些普通字符和元字符組成的編程語言
^
: 會匹配字符串或者行的起始位置, 在 [ ] 中表示 ''非''(!)$
: 會匹配字符串或行的結束位置 (在 \n 以前)^
,$
一塊兒則表示精確匹配包裹在兩個符號之間的字符串\A
: 指定匹配必須出如今字符串的開頭(忽略 Multiline 選項)\Z
: 指定匹配必須出如今字符串的結尾或字符串結尾的 \n 以前(忽略 Multiline 選項)✳
: 重複零次或更多 (>=0)函數
✚
: 重複一次或更屢次 ( >=1)工具
❔
: 重複零次或一次 (0 || 1)spa
{}
: 重複多少次的意思 能夠有多少個.net
函數 | 說明 |
---|---|
re.match( ) | 從字符串的起始位置匹配, 匹配成功, 返回一個匹配的對象, 不然返回None |
re.search( ) | 掃描整個字符串並返回第一個成功的匹配 |
re.findall( ) | 在字符串中找到正則表達式所匹配的全部子串, 並返回一個列表, 若是沒有找到匹配的, 則返回空列表 |
re.split( ) | 將一個字符串按照正則表達式匹配結果進行分割, 返回列表類型 |
re.finditer( ) | 在字符串中找到正則表達式所匹配的全部子串, 並把它們做爲一個迭代器返回 |
re.sub( ) | 把字符串中全部匹配正則表達式的地方替換成新的字符串 |
re.complie( ) | 將正則表達式傳入, 返回一個匹配對象, 通常與其餘方法組合使用 |
print("hello".replace("llo","ooo")) # heooo print("hello".find("abcd")) # -1 (找不到返回 -1) print("hello".find("he")) # 0
\w
和 \W
import re print(re.findall("\w","ab* 12$ _")) # ['a', 'b', '1', '2', '_'] print(re.findall("\W","ab* 12$ _")) # ['*', ' ', '$', ' ']
\s
和 \S
print(re.findall("\s","ab* 12$ _ ")) # [' ', ' ', ' '] print(re.findall("\S","ab* 12$ _ ")) # ['a', 'b', '*', '1', '2', '$', '_']
\d
和 \D
print(re.findall("\d","ab* 12$ _")) # ['1', '2'] print(re.findall("\D","ab* 12$ _")) # ['a', 'b', '*', ' ', '$', ' ', '_']
\A
和 \Z
print(re.findall("\Aab","ab* 12$ _")) # ['ab'] print(re.findall("\Aaa","ab* 12$ _")) # [] 沒匹配到爲空 print(re.findall("_\Z","ab* 12$ _")) # ['_'] print(re.findall("0\Z","ab* 12$ _")) # [] 沒匹配到爲空
\t
和 \n
print(re.findall("\t","ab* 12$ \t_")) # ['\t'] print(re.findall("\n","ab* 12$ \n_")) # ['\n'] 🔰"\s" 能夠匹配"\t"和"\n" print(re.findall("\s","ab* \t12$ _\n")) # [' ', '\t', ' ', '\n']
^
和 \$
print(re.findall("^ab","ab* 12$ _")) # ['ab'] print(re.findall("_$","ab* 12$ _\n")) # ['_']
▪
: 匹配一個任意字符print(re.findall("a.b","a&b")) # ['a&b'] print(re.findall("a.b","a2b")) # ['a2b'] print(re.findall("a.b","acb")) # ['acb'] print(re.findall("a.b","a b")) # ['a b'] print(re.findall("a.b","a\tb")) # ['\t'] print(re.findall("a.b","a\nb")) # [] (換行符匹配不到,匹配爲空) print(re.findall("a.b","a b a*b abb a_b")) # ['a b', 'a*b', 'abb', 'a_b'] print(re.findall("a.b","a\nb",re.S)) # ['a\nb'] (加入參數, 包含換行) print(re.findall("a.b","a\nb",re.DOTALL)) # ['a\nb'] (同上效果同樣)
✳
: 匹配零個或多個print(re.findall("a*","aaaa aa")) # ['aaaa', '', 'aa', ''] (零個或多個a) print(re.findall("ab*","abab aa")) # ['ab', 'ab', 'a', 'a'] (一個a零個或多個b) print(re.findall("a*b","ababaaaba aa")) # ['ab', 'ab', 'aaab'] (零個或多個a一個b) print(re.findall("ab*","bbbbbbbb")) # [] (沒有匹配到一個a零個或多個b)
❔
: 匹配零個或一個print(re.findall("ab?","a")) # ['a'] print(re.findall("ab?","abbb")) # ['ab']
✚
: 匹配一個或多個print(re.findall("a+","bbb")) # [] print(re.findall("a+","ab")) # ['a'] print(re.findall("ab+","ab")) # ['ab'] print(re.findall("ab+","abbb")) # ['abbb']
{n,m}
: 匹配 n~m 之間個print(re.findall("a{9}","aaaa")) # [] (匹配9個b,沒有) print(re.findall("a{3}","aaaa")) # ['aaa'] print(re.findall("a{2}","aaaa")) # ['aa', 'aa'] print(re.findall("ab{2}","aabbb")) # ['abb'] print(re.findall("ab{2,6}","abbb")) # ['abbb'] (一個a,2~6個b) print(re.findall("ab{1,}","abbb")) # ['abbb'] (至關於 ab+) print(re.findall("ab{0,}","abbb")) # ['abbb'] (至關於 ab*)
[ ]
: 放一組字符,逐個匹配print(re.findall("a[*1_c-]b","a*ba1b a_baaba-b")) # ['a*b', 'a1b', 'a_b', 'a-b'] print(re.findall("a[^*1c-]b","a*ba1b a_baab")) # ['a_b', 'aab'] (匹配非 [] 內的字符) print(re.findall("a[0-9]b","a*ba1b a3baa2b")) # ['a1b', 'a3b', 'a2b'] (0~9) print(re.findall("a[a-z]b","a*banb apbaaob")) # ['anb', 'apb', 'aob'] (a~z) print(re.findall("a[a-zA-Z0-9]b","a*banb aPbaa7b")) # ['anb', 'aPb', 'a7b'] print(re.findall("a[^a-zA-Z0-9]b","a*banb aPbaa7b")) # ['a*b'] (非a~z,A~Z,0~9)
( )
: 分組print(re.findall('ab+','ababab123')) # ['ab', 'ab', 'ab'] print(re.findall('(ab)+123','ababab123')) # ['ab'],匹配到末尾的 ab123 中的 ab print(re.findall('(?:ab)+123','ababab123')) # findall的結果不是匹配的所有內容,而是組內的內容, ?: 可讓結果爲匹配的所有內容 print(re.findall('href="(.*?)"','<a href="http://www.baidu.com">點擊</a>')) # ['http://www.baidu.com'] print(re.findall('href="(?:.*?)"','<a href="http://www.baidu.com">點擊</a><a href="http://www.aiqiyi.com">點擊2</a>')) # ['href="http://www.baidu.com"', 'href="http://www.aiqiyi.com"']
a|b
: 左右兩邊都匹配print(re.findall("shawn|song","shawn is man song is shawn")) # ['shawn', 'song', 'shawn'] (不加括號全局匹配) print(re.findall("A(?:abc|cba)A","AabcA")) # ['AabcA'] print(re.findall("com(?:puter|e)","come on! Here is a computer ")) # ['come', 'computer']
\
: 轉義字符# 轉義字符,使後一個字符改變原來的意思。 # 若是字符串中有字符 * 須要匹配,可使用 \* 或者字符集 [*] print(re.findall("a.b","a1b a.b")) # ['a1b', 'a.b'] print(re.findall("a\.b","a1b a.b")) # ['a.b']
print(re.findall("\d+\.?\d*","12as3.45qw2k7")) # ['12', '3.45', '2', '7']
.*
貪婪匹配示例print(re.findall("a.*b","a11b22222b33")) # ['a11b22222b']
.*?
非貪婪匹配示例print(re.findall("a.*?b","a11b22222b3")) # ['a11b']
print(re.findall("abc","112abc333")) # ['abc'] print(re.findall("abcd","12abc333")) # []
print(re.search("abc","112abc333abc")) # <re.Match object; span=(3, 6), match='abc'> print(re.search("abc","112abc333abc").group()) # abc print(re.search("abcd","12abc333abc")) # None print(re.search("abcd","12abc333abc").group()) # 報錯 "AttributeError" (由於沒拿到這個對象,因此沒有group()屬性
print(re.match("abc","abc22abc")) # <re.Match object; span=(0, 3), match='abc'> print(re.match("abc","abc22abc").group()) # abc print(re.match("abc","1abc22abc")) # None print(re.search("^abc","1abcabc")) # None (re.search)
[ ]
則是逐個匹配print(re.split("o","abcoabcoabc")) # ['abc', 'abc', 'abc'] print(re.split("ab","abcoabcoabc")) # ['', 'co', 'co', 'c'] print(re.split("d","abcoabcoabc")) # ['abcoabcoabc'] (沒匹配到返回原字符串) print(re.split("[o]","abcoabcoabc")) # ['abc', 'abc', 'abc'] print(re.split("[ob]","abcoabcoabc")) # ['a', 'c', 'a', 'c', 'a', 'c'] print(re.split("[oba]","abcoabcoabc")) # ['', '', 'c', '', '', 'c', '', '', 'c'] # 先使用"o"匹配進行分隔, 獲得結果"['abc', 'abc', 'abc']", 在使用"b"進行匹配分隔,獲得結果後再使用"a"匹配進行分隔
print(re.sub("a","A","i am a man")) # i Am A mAn print(re.sub("a","b","i am a man")) # i bm b mbn print(re.sub("am","b","i am a man")) # i b a man print(re.sub("a","AA","i am a man")) # i AAm AA mAAn print(re.sub("a","A","i am a man",1)) # i Am a man print(re.sub("a","A","i am a man",2)) # i Am A man print(re.sub("a","A","i am a man",3)) # i Am A mAn print(re.sub("a","A","i am a man",9)) # i Am A mAn (超出字符串中最大的個數不會報錯,而是替換全部) print(re.subn("a","A","i am a man")) # ('i Am A mAn', 3) (顯示替換的個數) print(re.subn("a","A","i am a man",2)) # ('i Am A man', 2)
obj = re.compile("\d{2}") print(obj) # re.compile('\\d{2}') print(obj.findall("ab12c33b44")) # ['12', '33', '44'] print(obj.search("ab12c33b44").group()) # 12 print(obj.match("12c33b44").group()) # 12 (注意,必須在開頭就匹配到,否則group會報錯)
字符 | 描述 |
---|---|
(?:pattern) | 匹配pattern, 但不捕獲匹配結果。 |
(?=pattern) | 零寬度正向預查,不捕獲匹配結果。 |
(?!pattern) | 零寬度負向預查,不捕獲匹配結果。 |
(?<=pattern) | 零寬度正向回查,不捕獲匹配結果。 |
(?<!pattern) | 零寬度負向回查,不捕獲匹配結果。 |
?! pattern
,表示在沒有配到pattern的字符串的前提下,再進行後續的正則表達式匹配,後續匹配仍然從被匹配字符串的頭開始🍓 匹配密碼,密碼必須是由6位數字與字母組成,而且不能是純數字也不能是純字母 while 1: passwd = input(">>").strip() res = re.match("(?![\d]+$)(?![a-zA-Z]+$)[\da-zA-Z]{6}$",passwd) if res: print(f"密碼:{res.group()}") else: print("密碼不符合規則")
?= pattern
,表示在配到pattern的字符串的前提下,再進行後續的正則表達式匹配,後續匹配仍然從被匹配字符串的頭開始🍓 匹配密碼,必須包含大寫,小寫和數字,和特殊字符(!,@,#,%,&),且大於6位 while 1: passwd = input("請輸入密碼>>").strip() res = re.search("(?=.*[\d])(?=.*[a-z])(?=.*[A-Z])(?=.*)(?=.*[!@#%&])^([\da-zA-Z!@#%&]{7,})$",passwd) if res: print(res.group()) else: print("密碼強度不夠")