Python 正則表達式

定義

在編寫處理字符串的程序或網(wǎng)頁時,經(jīng)常會有查找符合某些復(fù)雜規(guī)則的字符串的需要陋葡。正則表達式就是用于描述這些規(guī)則的工具亚亲。

簡而言之:正則表達式就是記錄文本規(guī)則的代碼。

特點:

操作字符串

1.更快的方式操作字符串腐缤;(表單校驗捌归,數(shù)據(jù)匹配...)

2.普通字符串操作無法做到的,或者很難做的正則很容易搞定A朐痢O鳌!

使用場景:

1.表單校驗

2.api 里面也需要正則

3.[\u4e00-\u9fa5] 中文匹配 Unicode 編碼中文匹配

正則表達式代碼體驗

# Python 解釋器為我們提供了一個使用正則的模塊剃浇,這個模塊叫做re(regex)
import re

if __name__ == '__main__':
    # 1.match():匹配 -> object
    # group():通過匹配后门扇,可以使用group()獲取內(nèi)容
    obj = re.match(r"jovelin", "jovelin")
    print(obj.group())  # -> jovelin

    # 2.如果被匹配的內(nèi)容多余正則;(只返回開頭匹配的部分)
    obj = re.match(r"jovelin", "jovelin.cn")
    print(obj.group())  # -> jovelin

    # 3.如果開頭部分偿渡,沒有匹配的內(nèi)容臼寄; 那么返回None
    obj = re.match(r"jovelin", "www.jovelin.cn")
    print(obj)  # -> None

    print(None, type(None))  # -> None <class 'NoneType'>

常用的元字符

語法 說明
. 匹配除換行符(\n)以外的任意字符
[] 匹配 [ ] 中列舉的字符
\w | \W 匹配字母或數(shù)字或下劃線或漢字 | 反義
\s | \S 匹配任意的空白符 | 非空白
\d | \D 匹配數(shù)字 [0-9] | 非數(shù)字
\b | \B 匹配單詞的開始或結(jié)束 | 反義
^ 匹配字符串的開始
$ 匹配字符串的結(jié)束

代碼演示:

# . 匹配任意1個字符(除了 \n)
print(re.match(r'a.b', 'a\nb'))  # -> None
#  - 在 [] 里代表范圍
print(re.match(r'a[a-c]c', 'abc').group())  # -> abc
# 在 [] 里面也想使用 - 那么需要 \ 轉(zhuǎn)義
print(re.match(r'a[a\-c]c', 'a-c').group())  # -> a-c
# \b用法 與 ^ $ 相似,不過 \b 只匹配單詞溜宽,\B 只匹配非單詞
print(re.match(r"\b\w+\b", "0_9_a_z_A_Z漢字").group())  # -> 0_9_a_z_A_Z
print(re.match(r"\B\W+\B", "!@#$%^&*").group())  # -> !@#$%^&*
# ^ 匹配字符串開頭
# $ 匹配字符串結(jié)尾
print(re.match(r'[\w\W]*$', '0_9_a_z_A_Z漢字!@#$%^&* \n\t').group())  # -> 0_9_a_z_A_Z漢字!@#$%^&* 
    
# 注意: ^ 如果出現(xiàn)在 [] 中吉拳,代表的是取反!   (想要使用 ^,可以轉(zhuǎn)義 \)
print(re.match(r'^[\^]$', '^').group())  # -> ^
print(re.match(r'^[^^]$', '^'))  # -> None
print(re.match(r'^[^47]$', '47'))  # -> 47

常用的限定符(量詞)

語法 說明 備注
* 重復(fù)零次或更多次 >=0
+ 重復(fù)一次或更多次 >=1
? 重復(fù)零次或一次 0|1
{n} 重復(fù)n次 ==n
{n,} 重復(fù)n次或更多次 >=n
{n,m} 重復(fù)n到m次 n<=X<=m

代碼演示:

# * 匹配前一個字符出現(xiàn)0次或者無限次,即可有可無 (>=0)
print(re.match(r'a*b', 'b').group())  # -> b
# + 匹配前一個字符出現(xiàn)1次或者無限次适揉,即至少有1次 (>=1)
print(re.match(r'a+b', 'b'))  # -> None留攒,必須要 1 個 a
# {n} 匹配前一個字符出現(xiàn)n次 == n                           (== n)
print(re.match(r'a{2}b', 'ab'))  # -> None,必須要 2 個 a
# {n,m} 匹配前一個字符出現(xiàn): n次<= 前一個字符 <=m次 (n<=X<=m)
print(re.match(r'a{2,5}b', 'ab'))  # -> None嫉嘀,a 的次數(shù)必須是 2<=a<=5

案例

1.校驗手機號

import re


def isMobileNumber(tel):
    """
    校驗手機號是否正確
    """
    if re.match(r"^[1-][34578-]\d{9}$", tel) is None:
        return False
    else:
        return True


print(isMobileNumber("18819950820"))

2.校驗郵箱

import re

"""
郵箱名稱部分為: [a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+){0,4}
域名部分: [a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+
連起來 ^[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+){0,4}@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+){1,2}$
"""


def isEmail(email):
    """校驗郵箱是否正確"""
    if re.match(r"^[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+){0,4}@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+){1,2}$", email) is None:
        return False
    else:
        return True


print(isEmail("jovelin@163.com"))
print(isEmail("jovelin.dev@gmail.com"))
print(isEmail("jovelin@163.com.cn"))
print(isEmail("jovelin.dev@gmail.com.cn"))

分組

用小括號來指定子表達式(也叫做分組)炼邀,然后你就可以指定這個子表達式的重復(fù)次數(shù)了,你也可以對子表達式進行其它一些操作剪侮。

語法 說明
(abc) 將括號中字符作為一個分組
| 匹配左右任意一個表達式
\num 引用分組num匹配到的字符串
(?P<name>) 分組起別名
(?P=name) 引用別名為name分組匹配到的字符串

代碼演示:

# (abc) 將括號中字符作為一個分組
print(re.match(r'(aaa)bbb(ccc)', 'aaabbbccc').group())
# 一個括號就是一個分組拭宁; group():參數(shù)代表分組的編號镇匀;寫 0 或者不寫時敬锐,獲取全部;
print(re.match(r'(aaa)bbb(ccc)', 'aaabbbccc').group())
print(re.match(r'(aaa)bbb(ccc)', 'aaabbbccc').group(0))
print(re.match(r'(aaa)bbb(ccc)', 'aaabbbccc').group(1))

# | 匹配左右任意一個表達式(和 [] 相似)
print(re.match(r'aaa(xxx|yyy|zzz)bbb', 'aaaxxxbbb').group())

# \num 引用分組 num 匹配到的字符串
#       前后保證一致纵竖,要使用到分組彩匕!
print(re.match(r'^<(\w+)>\w+</\1>$', '<html>nihao</html>').group())
print(re.match(r'^<(\w+)><(\w+)>\w+</\2></\1>$', '<html><div>nihao</div></html>').group())

# (?P<name>正則)  分組起別名
# (?P=name)       引用別名為name分組匹配到的字符串
print(re.match(r'^<(?P<re1>\w+)><(?P<re2>\w+)>\w+</(?P=re2)></(?P=re1)>$', '<html><div>jovelin</div></html>').group())

正則高級 API(4個)

語法 說明
search() 搜索字符串中符合正則表達式的內(nèi)容 -> 只返回第一個
findall() 搜索字符串中符合正則表達式的內(nèi)容 -> 返回一個列表
sub() 替換字符串中符合正則的內(nèi)容 -> 替換后的字符串
split() 按照指定正則切割字符串 -> 返回列表

代碼演示:

import re

# 1.search()
print(re.search(r"\d+", "aaa111bbb222ccc333ddd").group())

# 2.findall()
print(re.findall(r"\d+", "aaa111bbb222ccc333ddd"))

# 3.sub()
print(re.sub(r"\d+", "***", "aaa111bbb222ccc333ddd"))
# sub(正則, 替換成***, 被操作的字符串, 替換次數(shù))
print(re.sub(r"\d+", "***", "aaa111bbb222ccc333ddd", 2))

# 4.split()
print(re.split(r"\d+", "aaa111bbb222ccc333ddd eee"))
print(re.split(r"\d+|\s", "aaa111bbb222ccc333ddd eee"))

r 的作用

讓程序把正則直接當(dāng)做正則看腔剂;(不是從字符串開始解釋)

# c:\aaa\bbb\ccc
print('c:\aaa\bbb\ccc')
print('c:\\aaa\\bbb\\ccc')

# 問題:在字符串中寫 \ 時會轉(zhuǎn)義,需要寫成 \\
# 不寫 r 時 \\\\ -> \\
print(re.match('c:\\\\aaa\\\\bbb\\\\ccc', 'c:\\aaa\\bbb\\ccc').group())
# 寫 r 時 \\ -> \\
print(re.match(r'c:\\aaa\\bbb\\ccc', 'c:\\aaa\\bbb\\ccc').group())

貪婪/非貪婪

貪婪:(量詞在自己的范圍內(nèi)驼仪,取最多...)

非貪婪:(量詞在自己的范圍內(nèi)掸犬,取最少... )

非貪婪用法:量詞后面加?

print('貪婪', re.match(r'a+', 'aaa').group())  # -> aaa
# 量詞后面加?
print('非貪婪', re.match(r'a+?', 'aaa').group())  # -> a
print('貪婪', re.match(r'a{1,2}', 'aaa').group())  # -> aa
# 量詞后面加?
print('非貪婪', re.match(r'a{1,3}?', 'aaa').group())  # -> a

更多參考內(nèi)容: http://deerchao.net

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末袜漩,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子湾碎,更是在濱河造成了極大的恐慌宙攻,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件胜茧,死亡現(xiàn)場離奇詭異粘优,居然都是意外死亡,警方通過查閱死者的電腦和手機呻顽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門雹顺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人廊遍,你說我怎么就攤上這事嬉愧。” “怎么了喉前?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵没酣,是天一觀的道長。 經(jīng)常有香客問我卵迂,道長裕便,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任见咒,我火速辦了婚禮偿衰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘改览。我一直安慰自己下翎,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布宝当。 她就那樣靜靜地躺著视事,像睡著了一般。 火紅的嫁衣襯著肌膚如雪庆揩。 梳的紋絲不亂的頭發(fā)上俐东,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機與錄音盾鳞,去河邊找鬼犬性。 笑死,一個胖子當(dāng)著我的面吹牛腾仅,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播套利,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼推励,長吁一口氣:“原來是場噩夢啊……” “哼鹤耍!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起验辞,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤稿黄,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后跌造,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體杆怕,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年壳贪,在試婚紗的時候發(fā)現(xiàn)自己被綠了陵珍。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡违施,死狀恐怖互纯,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情磕蒲,我是刑警寧澤留潦,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站辣往,受9級特大地震影響兔院,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜站削,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一坊萝、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧钻哩,春花似錦屹堰、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至珊肃,卻和暖如春荣刑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背伦乔。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工厉亏, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人烈和。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓爱只,卻偏偏與公主長得像,于是被迫代替她去往敵國和親招刹。 傳聞我的和親對象是個殘疾皇子恬试,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容