文章目錄
- 正規表達式與re子產品
-
- 一 什麼是正規表達式
- 二 為什麼有正規表達式
- 三 正規表達式如何使用
-
- 1 正規表達式的基本用法
-
- 1.1 元字元
- 1.2.重複限定符
- 1.3.分組——"()"
- 1.4.轉義——" \ "
- 1.5.條件或——"|"
- 1.6.區間——"[]"
- 2 在python中使用re子產品
-
- 2.1 python中常用的元字元及其含義
- 2.2 普通比對示例
- 2.3 正則比對示例
-
- 2.3.1 `\w`
- 2.3.2 `\W`
- 2.3.3 `\s`
- 2.3.4 `\S`
- 2.3.5 `\d`
- 2.3.6 `\D`
- 2.3.7 `\n與\t`
- 2.3.8 `^與$`
- 2.3.9 `. 與[]、中括号内取反、*、+、{n,m}、?、. *、`
- 2.3.10 `():分組及取消分組`
- 2.3.11 `|:或者`
- 2.3.12 `\ 轉義符`
- 2.4 re子產品提供的方法介紹
-
- 2.4.1 `re.findall(pattern, string, flags=0)`
- 2.4.2 `re.search(pattern, string, flags=0)`
- 2.4.3 `re.match(pattern, string, flags=0)`
- 2.4.4 `re.split(self, *args, **kwargs)`
- 2.4.5 `re.compile(pattern, flags=0)`
- 3 正規表達式的進階用法
-
- 3.1 零寬斷言
-
- 3.1.1 斷言
- 3.1.2 零寬
- 3.1.3 斷言類型之:正向先行斷言(正前瞻)
- 3.1.4 斷言類型之:正向後行斷言(正後顧)
- 3.1.5 斷言類型之:負向先行斷言(負前瞻)
- 3.1.6 斷言類型之:負向後行斷言(負後顧)
- 3.2 捕獲和非捕獲
-
- 3.2.1 數字編号捕獲組
- 3.2.2 命名編号捕獲組
- 3.2.3 非捕獲組
- 3.3.反向引用
- 3.4 貪婪和非貪婪
-
- 3.4.1 貪婪
- 3.4.2 懶惰(非貪婪)
- 4 python中應用案例:
正規表達式與re子產品
一 什麼是正規表達式
由一系列特殊字元拼接而成的表達式/規則,它描述了一種字元串比對的模式。
在python中,它内嵌在Python解釋器中,并通過re子產品實作。正規表達式被編譯成一系列的位元組碼,然後由用C編寫的比對引擎執行。
二 為什麼有正規表達式
正規表達式用于從一個大字元串中比對出符合規則的子字元串。
三 正規表達式如何使用
1 正規表達式的基本用法
1.1 元字元
萬物有源,正則也是如此,元字元是構成正規表達式的一種基本元素。
# 基本的元字元:
元字元 | 說明 |
---|---|
. | 比對除換行符以外的任意字元 |
\w | 比對字母或數字或下劃線或漢字 |
\s | 比對任意的空白符 |
\d | 比對任意數字 |
\b | 比對單詞的開始或結束 |
^ | 比對字元串的開始 |
$ | 比對字元串的結束 |
有了元字元之後,我們就可以利用這些元字元來寫一些簡單的正規表達式,比如:
1.2.重複限定符
為了處理重複的書寫元字元的問題,正規表達式提供了一些重複限定符,把重複部分用何使的限定符替代:
文法 | 說明 |
---|---|
* | 左側字元重複零次或更多次 |
+ | 左側字元重複一次或更多次 |
? | 左側字元重複零次或一次 |
{n} | 左側字元重複n次 |
{n, } | 左側字元重複n次或更多次 |
{n, m} | 左側字元重複n到m次 |
1.3.分組——"()"
限定符是作用在與他左面最近的一個字元身上,若想要兩個或兩個以上字元同時被限定,則需要使用到小括号()來做分組,也就是括号中的内容作為一個整體。
文法 | 說明 |
---|---|
(ab) | 根據分組條件限定,但僅顯示分組内的内容ab |
(?:ab) | 根據分組條件限定,但是不僅僅顯示分組内的内容,?: 取消了僅顯示分組内容的限制 |
1.4.轉義——" \ "
我們知道了()在表達式内有分組這一特殊的含義,那麼我們如何進行比對字元串本身就包括特殊意義的符号呢?針對這種情況,正則提供了轉義的方式,也就是要把這些元字元、限定符或者關鍵字轉義成普通的字元,就是在這些字元前面加一個" \ ",可以實作轉義效果。
由于python中" \ "也有轉義的效果,那麼:
# 字元串"a\c"如何使用正則子產品進行比對?有兩種方式:
1) "a\\\\c"
2) r"a\\c"
"""
解析:
python文法進行了一次轉義,而Cpython解釋器自帶的正則子產品又進行了一次轉義,兩次轉義,解決python文法中的轉義可以使用"\"或者原生字元串r解決,正則中的隻能使用"\"解決。
"""
1.5.條件或——"|"
正則中針對并列的條件,提供了"|"代表“或”,也叫分支條件,當滿足正則中分支條件的任一條件時,都會當成是比對成功。
1.6.區間——"[]"
正則中提供了一個元字元中括号來表示區間條件,也可以了解為區間内的字元,屬于或關系。
元字元 | 說明 |
---|---|
[0-9] | 代表限定條件是0-9中的任意數字。 |
[a-zA-Z] | 代表限定條件是英文字母,[a-z]可單獨代表小寫字母。 |
[-+] | 限定字元是"-“或”+",當"-"不代表區間範圍含義時,必須放在開始或末尾。 |
2 在python中使用re子產品
2.1 python中常用的元字元及其含義
模式 | 含義 |
---|---|
\w | 比對字母、數字、下劃線及漢字 |
\W | 比對非字母、數字、下劃線及漢字 |
\s | 比對任意空白字元,等價于[\t\n\r\f] |
\S | 比對任意非空字元 |
\d | 比對任意數字,等價于[0-9] |
\D | 比對任意非數字 |
\A | 比對字元串開始 |
\Z | 比對字元串結束,如果是存在換行,隻比對到換行前的結束字元串 |
\z | 比對字元串結束 |
\G | 比對最後比對完成的位置 |
\n | 比對一個換行符 |
\t | 比對一個制表符 |
^ | 比對字元串的開頭 |
$ | 比對字元串的末尾 |
. | 比對任意字元,除了換行符,當 标記被指定時,則可以比對包括換行符的任意字元 |
[…] | 用來表示比對一組字元串,單獨列出:[amk]比對"a",“m"或"k”,特殊字元在中括号内沒有特殊含義 |
[^…] | 不在[]中的字元:若…代表abc,則比對除a,b,c外的任意字元 |
* | 比對0個或多個,貪婪方式 |
+ | 比對1個或多個,貪婪方式 |
? | 比對0個或一個由前面的正規表達式定義的片段, 非貪婪方式限定 |
{n} | 精确比對n個前面表達式 |
{n, m} | 比對n到m次由前面的正規表達式定義的片段,貪婪方式 |
a|b | 比對a或b |
() | 比對括号内的表達式,也表示一個組 |
2.2 普通比對示例
# 一對一的比對
'hello'.replace(old,new)
'hello'.find('partten')
2.3 正則比對示例
2.3.1 \w
\w
2.3.2 \W
\W
2.3.3 \s
\s
print(re.findall('\s', "h e\tll\no 123_ (0")) # [' ', '\t', '\n', ' ', ' ']
print(re.findall('\w\s',"h ello 123_ (0")) # ['h ', 'o ', '_ ']
2.3.4 \S
\S
2.3.5 \d
\d
2.3.6 \D
\D
2.3.7 \n與\t
\n與\t
msg = """h e\tll\n\no 123_ (0
\t1
2
3
"""
print(re.findall('\n', msg)) # ['\n', '\n', '\n', '\n', '\n', '\n']
print(re.findall('\t', msg)) # ['\t', '\t']
print(re.findall(' ', msg)) # [' ', ' ', ' ', ' ', ' ', ' ', ' ']
2.3.8 ^與$
^與$
print(re.findall("^egon", "egon asdf 213123 egonafsadfegon")) # ['egon']
print(re.findall("egon$", "egon asdf 213123 egonafsadfegon")) # ['egon']
print(re.findall("egon$", "egon asdf 213123 egonafsadfegon ")) # []
print(re.findall("a\w\w\wc", "ab12c3c a213c")) # ['ab12c', 'a213c']
print(re.findall("^a\w\w\wc$", "ab12c3c a213c")) # []
print(re.findall("^a\w\w\wc$", "ab_2c")) # ['ab_2c']
2.3.9 . 與[]、中括号内取反、*、+、{n,m}、?、. *、
. 與[]、中括号内取反、*、+、{n,m}、?、. *、
2.3.9.1
"."
代表比對一個字元,該字元可以是任意除換行符外的字元
print(re.findall("a\db", "a1b a2b aab aaaaaaab a+b a-b a c")) # ['a1b', 'a2b']
print(re.findall("a\wb", "a1b a2b aab aaaaaaab a+b a-b a c")) # ['a1b', 'a2b', 'aab', 'aab']
print(re.findall("a.b", "a1b a2b aab aaaaaaab a+b a-b a b a c")) # ['a1b', 'a2b', 'aab', 'aab', 'a+b', 'a-b', 'a b']
print(re.findall("a.b", "a1b a2b aab aaaaaaab a\tb a-b a\nb a c", re.DOTALL)) # ['a1b', 'a2b', 'aab', 'aab', 'a\tb', 'a-b', 'a\nb']
2.3.9.2
[]
:代表比對一個字元,我們可以指定該字元的範圍,特殊字元在[]内就沒有特殊含義了
print(re.findall("a[+-]b", "a1b a2b aab aaaaaaab a+b a-b a c")) # ['a+b', 'a-b']
print(re.findall("a[.*/+-]b", "a.b a2b a*b a/b aab aaaaaaab a+b a-b a c")) # ['a.b', 'a*b', 'a/b', 'a+b', 'a-b']
print(re.findall("a[a-z]b", "a.b a2b a*b a/b aab aaaaaaab a+b a-b a c")) # -放在[]内的開頭或結果
# ['aab', 'aab']
print(re.findall("a[a-zA-Z]b", "a.b a2b a*b a/b aAb aCb aab aaaaaaab a+b a-b a c")) # -放在[]内的開頭或結果
# ['aAb', 'aCb', 'aab', 'aab']
print(re.findall("a\db", "a.b a2b a*b a/b aAb aCb aab aaaaaaab a+b a-b a c")) # ['a2b']
print(re.findall("a[0-9]b", "a.b a2b a*b a/b aAb aCb aab aaaaaaab a+b a-b a c")) # ['a2b']
2.3.9.3
[^]
對上尖号後的内容取反
2.3.9.4
*
: 左邊那個字元出現0次或者無窮次
2.3.9.5
+
: 左邊那個字元出現1次或者無窮次
2.3.9.6
{n,m}
: 左邊那個字元出現n次到m次
print(re.findall("ab{0,}", "a ab abb abbbbbbbbbbbb bbbbbbbbb")) # ['a', 'ab', 'abb', 'abbbbbbbbbbbb']
print(re.findall("ab*", "a ab abb abbbbbbbbbbbb bbbbbbbbb")) # ['a', 'ab', 'abb', 'abbbbbbbbbbbb']
print(re.findall("ab{1,}", "a ab abb abbbbbbbbbbbb bbbbbbbbb")) # ['ab', 'abb', 'abbbbbbbbbbbb']
print(re.findall("ab+", "a ab abb abbbbbbbbbbbb bbbbbbbbb")) # ['ab', 'abb', 'abbbbbbbbbbbb']
print(re.findall("ab{2,5}", "a ab abb abbb abbbb abbbbbbbb abbbbbbbbbbbb bbbbbbbbb")) # ['abb', 'abbb', 'abbbb', 'abbbbb', 'abbbbb']
2.3.9.7
?
: 左邊那個字元出現0次到1次,進行非貪婪限定
2.3.9.8
.*
: 比對所有(除換行符)
print(re.findall("a.*b", "123 a1231-==-000b123123123123123b")) # ['a1231-
print(re.findall("a.*?b", "123 a1231-==-000b123123123123123b")) # ['a1231-==-000b']
# 例1:re子產品可以将一個正則比對儲存起來
msg = '<a href="https://pan.baidu.com/s/1skWyTT7" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank"><strong><span style="color: #ff0000;">原理圖:https://pan.baidu.com/s/1skWyTT7</span></strong></a><a href="https://www.baidu/com" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" >"點我啊"</a>'
url_pattern = re.compile('href="(.*?)" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" ')
res = url_pattern.findall(msg)
print(res) # ['https://pan.baidu.com/s/1skWyTT7', 'https://www.baidu/com']
res = url_pattern.findall('<a href="www.sina.com.cn" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" ></a>') # ['www.sina.com.cn']
# 例2:當re.DOTALL标記被指定時,.可以比對包括換行符的任意字元
print(re.findall("a.*b", "a1b a+b a-b a\nb a\tb", re.DOTALL)) # ['a1b a+b a-b a\nb a\tb']
2.3.10 ():分組及取消分組
():分組及取消分組
print(re.findall('ab+', 'ababab123')) # ['ab', 'ab', 'ab']
print(re.findall('(ab)+123', 'ababab123')) # ['ab'],比對到末尾的ab123中的ab
print(re.findall('(?:ab)+123', 'ababab123')) # findall的結果不是比對的全部内容,而是組内的内容,?:可以讓結果為比對的全部内容
# ['ababab123']
2.3.11 |:或者
|:或者
print(re.findall("compan(?:ies|y)", "Too many companies have gone bankrupt, and the next one is my company'")) # ['companies', 'company']
print(re.findall("\d+\.?\d*", "as9fdasl333...4444df1111asdf3333dfadf333.44dafadf3.5555asdfsafd.5555")) # ['9', '333.', '4444', '1111', '3333', '333.44', '3.5555', '5555']
2.3.12 \ 轉義符
\ 轉義符
print(re.findall('a\\\\c','a\c a1c aac')) # ['a\\c']
print(re.findall(r'a\\c', 'a\c a1c aac')) # ['a\\c']
# 對于正則來說a\\c确實可以比對到a\c,但是在python解釋器讀取a\\c時,會發生轉義,然後交給re去執行,是以抛出異常
2.4 re子產品提供的方法介紹
2.4.1 re.findall(pattern, string, flags=0)
re.findall(pattern, string, flags=0)
# 找到所有,從頭找到尾,全部找出。
# .* ==> 任意字元 .*?==> 非貪婪限定後的
msg = '<a href="https://pan.baidu.com/s/1skWyTT7" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank"><strong><span style="color: #ff0000;">原理圖:https://pan.baidu.com/s/1skWyTT7</span></strong></a><a href="https://www.baidu/com" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" >"點我啊"</a>'
print(re.findall('href=".*?" target="_blank" rel="external nofollow" ', msg)) # ['href="https://pan.baidu.com/s/1skWyTT7" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" ', 'href="https://www.baidu/com" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" ']
print(re.findall('href=".*" target="_blank" rel="external nofollow" ', msg)) # ['href="https://pan.baidu.com/s/1skWyTT7" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank"><strong><span style="color: #ff0000;">原理圖:https://pan.baidu.com/s/1skWyTT7</span></strong></a><a href="https://www.baidu/com" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" >"點我啊"']
print(re.findall('e', 'alex make love')) # ['e', 'e', 'e'],傳回所有滿足比對條件的結果,放在清單裡
print(re.search('e', 'alex make love')) # <re.Match object; span=(2, 3), match='e'> e,隻到找到第一個比對然後傳回一個包含比對資訊的對象,該對象可以通過調用group()方法得到比對的字元串,如果字元串沒有比對,則傳回None。
2.4.2 re.search(pattern, string, flags=0)
re.search(pattern, string, flags=0)
# 從頭找到尾,找到第一個停下傳回輸出結果。加上.group()可以輸出實際的結果。
print(re.search("\d+\.?\d*", "1.3 aa3.44aaa").group()) # 1.3
print(re.search("\d+\.?\d*", "asdfsadf")) # None
2.4.3 re.match(pattern, string, flags=0)
re.match(pattern, string, flags=0)
# 從第一個字元開始比對,相當于^research。
print(re.search("\d+\.?\d*", " 1.3 aa3.44aaa")) # <re.Match object; span=(1, 4), match='1.3'>
print(re.match("\d+\.?\d*", "1.3 aa3.44aaa")) # <re.Match object; span=(0, 3), match='1.3'>
print(re.match("\d+\.?\d*", " 1.3 aa3.44aaa")) # None
2.4.4 re.split(self, *args, **kwargs)
re.split(self, *args, **kwargs)
# 字元串的切分。
msg = "egon:18-male=10"
print(msg.split(':')) # ['egon', '18-male=10']
print(re.split('[:=-]', msg)) # ['egon', '18', 'male', '10']
2.4.5 re.compile(pattern, flags=0)
re.compile(pattern, flags=0)
# re.compile()是用來優化正則的,它将正規表達式轉化為對象,re.search(pattern, string)的調用方式就轉換為 pattern.search(string)的調用方式,多次調用一個正規表達式就重複利用這個正則對象,可以實作更有效率的比對
# re.compile()生成的是正則對象,單獨使用沒有任何意義,需要和findall(), search(), match()搭配使用
msg = '<a href="https://pan.baidu.com/s/1skWyTT7" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank"><strong><span style="color: #ff0000;">原理圖:https://pan.baidu.com/s/1skWyTT7</span></strong></a><a href="https://www.baidu/com" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" >"點我啊"</a>'
url_pattern = re.compile('href="(.*?)" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" ')
res = url_pattern.findall(msg)
print(res) # ['https://pan.baidu.com/s/1skWyTT7', 'https://www.baidu/com']
res = url_pattern.findall('<a href="www.sina.com.cn" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" ></a>') # ['www.sina.com.cn']
3 正規表達式的進階用法
3.1 零寬斷言
3.1.1 斷言
-正則中的斷言,指的是正則可以指明在指定的内容的前面或後面會出現滿足指定規則的内容。意思是正則也可以像人類那樣斷定什麼什麼,比如"abc123def", 正則可以用斷言找出123前面有abc,也可以找出123後面有def。
3.1.2 零寬
-就是沒有寬度,在正則中,斷言隻比對位置,不占字元,也就是說,比對的結果不會傳回斷言本身。
3.1.3 斷言類型之:正向先行斷言(正前瞻)
文法:(?=pattern)
作用:比對pattern表達式之前的前面内容,不傳回本身。
3.1.4 斷言類型之:正向後行斷言(正後顧)
文法:(?<=pattern)
作用:比對pattern表達式的後面的内容,不傳回本身。
3.1.5 斷言類型之:負向先行斷言(負前瞻)
文法:(?!pattern)
作用:比對非pattern表達式前面的内容,不傳回本身。
3.1.6 斷言類型之:負向後行斷言(負後顧)
文法:(?<!pattern)
作用:比對非pattern表達式後面的内容,不傳回本身。
3.2 捕獲和非捕獲
單純說到捕獲,他的意思是比對表達式,但捕獲通常和分組聯系在一起,也就是”捕獲組“。
捕獲組:比對子表達式的内容,把比對結果儲存到記憶體中以數字編号或顯示命名的組裡,以深度優先進行編号,之後可以通過序号或名稱來使用這些比對結果。
3.2.1 數字編号捕獲組
文法:(exp)
解釋:從表達式左側開始,每出現一個左括号和它對應的右括号之間的内容為一個分組,在分組中,第0組為整個表達式,第一組開始為分組。
以固定電話為例:020-85653333
他的正規表達式為:(0\d{2})-(\d{8})
按照左括号的順序,這個表達式有如下分組:
序号 | 編号 | 分組 | 内容 |
---|---|---|---|
(0\d{2})-(\d{8}) | 020-85653333 | ||
1 | 1 | (0\d{2}) | 020 |
2 | 2 | (\d{8}) | 85653333 |
3.2.2 命名編号捕獲組
文法:(?< name>exp)
解釋:分組的命名由表達式中的name指定。
比如區号也可以這樣寫:(?< quhao>\0\d{2})-(?< haoma>\d{8})
按照左括号的順序,這個表達式有如下分組:
序号 | 編号 | 分組 | 内容 |
---|---|---|---|
(0\d{2})-(\d{8}) | 020-85653333 | ||
1 | quhao | (0\d{2}) | 020 |
2 | haoma | (\d{8}) | 85653333 |
3.2.3 非捕獲組
文法:(?:exp)
解釋:和捕獲組剛好相反,它用來辨別那些不需要捕獲的分組,說的通俗一點,就是可以根據需要去儲存你的分組。
比如上面的正規表達式,程式不需要用到第一個分組,那就可以這樣寫:
(?:\0\d{2})-(\d{8})
序号 | 編号 | 分組 | 内容 |
---|---|---|---|
(0\d{2})-(\d{8}) | 020-85653333 | ||
1 | 1 | (0\d{8}) | 85653333 |
3.3.反向引用
捕獲會傳回一個捕獲組,這個分組時儲存在記憶體中,不僅可以在正規表達式外部通過程式進行引用,也可以在正規表達式内部進行引用,這種引用方式就是反向引用。
根據捕獲組的命名規則,反向引用可分為:
1) 數字編号組反向引用:\k或\number
2) 命名編号組反向引用:\k或者\'name'
# 作用:
-它的作用主要是用來查找一些重複的内容或者做替換指定字元。與分組配合使用。
3.4 貪婪和非貪婪
3.4.1 貪婪
"貪婪比對":當正規表達式中包含能接受重複的限定符時,通常的行為是(在使整個表達式能得到比對的前提下) 比對盡可能多的字元,這比對方式叫做貪婪比對。
"特性":一次性讀入整個字元串進行比對,每當不比對就舍棄最右邊一個字元,繼續比對,依次比對和舍棄(這種比對-舍棄的方式也叫做回溯) ,直到比對成功或者把整個字元串舍棄完為止,是以它是一種最大化的資料傳回,能多不會少。
多個貪婪在一起時,如果字元串能滿足他們各自最大程度的比對時,就互不幹擾,但如果不能滿足時,會根據深度優先原則,也就是從左到右的每一個貪婪量詞,優先最大數量的滿足,剩餘再配置設定下一個量詞比對。
3.4.2 懶惰(非貪婪)
"懶惰比對":當正規表達式中包含能接受重複限定符時,通常的行為是(在使整個表達式能得到比對的前提下) 比對盡可能少的字元,這比對方式叫做懶惰比對。
"特性":從左到右,從字元串的最左邊開始比對,每次試圖不讀入比對字元,比對成功,則完成比對,否則讀入一個字元再比對,依次循環(讀入字元、比對) 直到比對成功或者把字元串的字元比對完為止。
懶惰量詞是在貪婪量詞後面加個"?"
代碼 | 說明 |
---|---|
*? | 重複任意次,但盡可能少重複 |
+? | 重複1次或更多次,但盡可能少重複 |
?? | 重複0次或一次,但盡可能少重複 |
{n, m}? | 重複n到m次,但盡可能少重複 |
{n, }? | 重複n次以上,但盡可能少重複 |
4 python中應用案例:
import re
# 1、比對密碼,密碼必須是由6位數字與字母組成,并且不能是純數字也不能是純字母
# 1.1 知識點:# ?!pattern,表示在沒有配到pattern的字元串的前提下,再進行後續的正規表達式比對,後續比對仍然從被比對字元串的頭開始
# 1.2 答案:
print(re.search("(?!^[0-9]+$)(?!^[a-zA-Z]+$)^[0-9A-Za-z]{6}$", "123asf").group()) # 123asf
# 1.3 解釋:
# 上述正則的意思為:在比對(?!^[0-9]+$)以及(?!^[a-zA-Z]+$)過後,如果字元串成功後再從頭去比對(?!^[a-zA-Z]+$),最終比對完。
while True:
pwd = input("please your password: ").strip() # 比如輸入:123asF
pwd_partten = re.compile("(?=.*[a-zA-Z])(?=.*[0-9])^([a-zA-Z0-9]){6}$")
if pwd_partten.search(pwd) is None:
print('密碼強度不夠')
else:
break
# 2、比對密碼,密碼強度:強,必須包含大寫,小寫和數字,和特殊字元(!,@,#,%,&),且大于6位
# 2.1 知識點:# ?=pattern,表示在配到pattern的字元串的前提下,再進行後續的正規表達式比對,後續比對仍然從被比對字元串的頭開始
# 2.2 答案:
while True:
pwd = input("please your password: ").strip() # 比如輸入:[email protected]
pwd_pattern = re.compile("(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[[email protected]#%&])^([[email protected]#%&]){6,}$")
if pwd_pattern.search(pwd) is None:
print("密碼強度不夠")
else:
break
# 2.3 解釋:
# 上述正規表達式的意思:
# (1) 首先是(?=.*[A-Z])比對,.*表示密碼中可以包含多個字元,[A-Z]代表密碼中需要包含至少一個大寫字母,注意一定不要去掉.*寫成(?=[A-Z]),那樣表示密碼隻能由一個字元組成,該字元是大寫字母
# (2) 其次是(?=.*[a-z])比對,同上,確定密碼中必須至少有一個小寫字母
# (3) 然後是(?=.*[0-9])比對,同上,確定密碼中必須至少有一個數字
# (4) 然後是(?=.*[[email protected]#%&])比對,同上,,確定密碼中必須至少有一個特殊符号[email protected]#%&
# (5) 最後是^([[email protected]#%&]){6,}$,確定密碼是由[[email protected]#%&]字元構成,至少有6位
# 3、比對email
print(re.findall("(?:[a-zA-Z0-9]+)@(?:[0-9a-zA-Z]+).com","[email protected] [email protected]"))
# 4、比對身份證
your_id=input(">>: ").strip()
print(re.findall("^([0-9]){17}([0-9]|X)$",your_id)) # 17個數字組成,最後一個字元可以是數字或X
print(re.findall("^(?:[0-9]){17}(?:[0-9]|X)$", "32032119920822222X")) # ['32032119920822222X']
# 5、比對使用者名,包含字母或者數字,且8位
print(re.findall("^[0-9a-zA-Z]{8}$","egonlinh"))
# 5.1、要求輸入的内容隻能是漢字
# name=input('>>: ').strip()
# print(re.search(r'[\u4E00-\u9fa5]+',name))
print(re.search(r"[\u4E00-\u9fa5]+", '矮根')) # <re.Match object; span=(0, 2), match='矮根'>
# 6、取出字元串裡的數字
# print(re.findall(r'\d+(?:\.\d+)?', 'sww123kw11.333e2lkd'))
print(re.findall(r"\d+(?:\.\d+)?", 'sww123kw11.333e2lkd')) # ['123', '11.333', '2']
#————————————————————————————# ?——>0或1個小數點及後續數字,為整數準備
print(re.findall(r"\d+(?:\.\d+)", 'sww123kw11.333e2lkd')) # ['11.333']
# 7、取出所有負整數
# print(re.findall(r'-\d+', '-12,3,54,-13.11,64,-9')) # 錯誤答案
# print(re.findall(r'(?!-\d+\.\d+)-\d+', '-12,3,54,-13.11,64,-9')) # 正确答案
print(re.findall(r'-\d+', '-12,3,54,-13.11,64,-9')) # 未排除浮點數
print(re.findall(r'(?!-\d+\.\d+)-\d+', '-12,3,54,-13.11,64,-9'))
#——————————————————# 先排除負數的浮點數
# 8、所有數字
# print(re.findall(r'\-?\d+(?:\.\d+)?', '-12.9,3.92,54.11,64,89,-9,-45.2'))
print(re.findall(r"\-?\d+(?:\.\d+)?", '-12.9,3.92,54.11,64,89,-9,-45.2')) # ['-12.9', '3.92', '54.11', '64', '89', '-9', '-45.2']
# 9、所有負數
# print(re.findall(r'\-\d+(?:\.\d+)?', '-12.9,3.92,54.11,64,89,-9,-45.2'))
print(re.findall(r"\-\d+(?:\.\d+)?", '-12.9,3.92,54.11,64,89,-9,-45.2')) # ['-12.9', '-9', '-45.2']
# 10、所有的非負浮點數
# print(re.findall(r'\d+\.\d+', '-12.9,3.92,54.11,64,89,-9,-45.2'))
print(re.findall(r"\d+(?:\.\d+)?", '-12.9,3.92,54.11,64,89,-9,-45.2')) # ['12.9', '3.92', '54.11', '64', '89', '9', '45.2']
# 11、
msg = """
中文名 貝拉克·侯賽因·奧_巴馬
外文名 Barack Hussein O_bama II
别名 歐_巴馬
性 别 男
國籍 美國
民 族 德裔族
出生地 美國夏威夷州檀香山
出生日期 1961年8月4日
職 業政治家、律師、總統
畢業院校 哥倫比亞大學,哈佛大學
信 仰新教
主要成就 1996年伊利諾伊州參議員
主要成就 美國第56屆、57屆總統 2009年諾貝爾和平獎獲得者 時代周刊年度風雲人物2008、2011 任期内清除本·拉登
代表作品 《我相信變革》《我父親的夢想》《無畏的希望》
所屬政黨美國民主黨
血 型 AB型
學 院西方學院
妻 子 米歇爾·拉沃恩·奧_巴馬
"""
# # 外文名
print(re.findall("外文名 (.*)", msg))
#
# # 出生日期
print(re.findall('出生日期 (\d{4})年(\d+)月(\d+)日', msg))
#
# # 妻子姓名
print(re.findall('妻 子 (\S+)', msg))
print(re.findall('妻 子 (.*)', msg))
參考資料:
https://juejin.im/post/6844903680349585422