正則表達式知識總結(jié)

1拌喉、前言

正則表達式俐银,如果有一定編程經(jīng)驗的同學尿背,一定知道,可能你知道捶惜,但又說不出個所以然來田藐,平時不經(jīng)常使用,很容易就忘記吱七,有一部分原因汽久,我認為是總結(jié)的內(nèi)容,不夠簡單和深刻踊餐。所以景醇,自己嘗試總結(jié)一下正則表達式的基礎(chǔ)知識點,對于大部分的編程場景應(yīng)該足夠使用啦市袖。另外啡直,也希望通過總結(jié),以便后續(xù)忘記時苍碟,能快速的記憶起來酒觅,這就是本文章的主要內(nèi)容。

2微峰、正則表達式

RegularExpression.png

匹配字符集

語法 匹配 示例
. 匹配任意字符(除了\n 表達式:. 匹配任意一個字符
[...] 匹配字符集(... 表示任意字符) 表達式:[a-zA-Z] 匹配任意一個小寫或大寫的字母舷丹。
表達式:[iHTC] 匹配 "i", "H", "T" 和 "C"。
表達式:[e-k] 匹配 "e" 到 "k" 之間的字符蜓肆。
\d 匹配數(shù)字 表達式:a\d颜凯,匹配字符串 "aaa123" 中的 a1 谋币。
表達式:a.\d,匹配字符串 "aaa123" 中的 aa1 症概。
\D 匹配非數(shù)字 表達式:a.\D蕾额,匹配字符串 "aaa123" 中的 aaa
\s 匹配空白字符(包括空格彼城、制表符诅蝶、換頁符等空白字符,[ \t\n\r\f] 表達式:a.\s募壕,匹配字符串 "aaa 123" 中的 aa(最后是空格) 调炬。
\S 匹配非空白字符 表達式:a.\S,匹配字符串 "aaa 123" 中的 aaa 舱馅。
\w 匹配單詞字符([a-zA-Z0-9_]和漢字) 表達式:a.\w,匹配字符串 "aaa 123" 中的 aaa 棘钞。
\W 匹配非單詞字符 表達式:a.\W资溃,匹配字符串 "aaa 123" 中的 aa(最后是空格) 。
\ 轉(zhuǎn)義字符 \r, \n 代表回車和換行符; \t 制表符; \\ 代表 "" 本身; \^ 匹配 ^ 符號本身; \$ 匹配 $ 符號本身; \. 匹配小數(shù)點(.)本身宝恶。

匹配量詞(Quantifier)

語法 匹配 示例
* 匹配表達式出現(xiàn) 0次或者無限次垫毙,相當于 {0,} 表達式:a*拱绑,匹配字符串 "aaa123" 中的 aaa
+ 匹配表達式至少出現(xiàn) 1次或者無限次膀藐,相當于 {1,} 表達式:a+额各,匹配字符串 "aaa123" 中的 aaa 吧恃。
? 匹配表達式 0次或者 1次,相當于 {0,1} 表達式:a?傲醉,匹配字符串 "aaa123" 中的 a 硬毕。
{m,n} 匹配表達式至少重復 m 次,最多重復 n 次 表達式:a{1,2}苞七,匹配字符串 "aaa123" 中的 aa 挪丢。
{m} 匹配表達式重復 m 次 表達式:a{3}乾蓬,匹配字符串 "aaa123" 中的 aaa 任内。
{m,} 匹配表達式至少重復 m 次 表達式:a{1,}融柬,匹配字符串 "aaa123" 中的 aaa
*? 匹配模式變?yōu)榉秦澙罚ūM可能少匹配字符)越除,匹配表達式可以為 0次摘盆,也可以是無限次 表達式:a[0-9]*?23',匹配字符串 "aaa123" 中的 a123 饱苟。
如果匹配字符串 "aaa23" 則為 a23
如果匹配字符串 "aaa456123" 則為 a456123 类垦。
+? 匹配模式變?yōu)榉秦澙罚ūM可能少匹配字符)蚤认,匹配表達式至少 1次酿傍,也可以是無限次 表達式:a[0-9]+?23,匹配字符串 "aaa123" 中的 a123 氯析。
如果匹配字符串 "aaa23" 則匹配失敗 掩缓。
如果匹配字符串 "aaa456123" 則為 a456123
?? 匹配模式變?yōu)榉秦澙罚ūM可能少匹配字符)巡通,匹配表達式最多 1次宴凉,也可以是 0次 表達式:a[0-9]??23表悬,匹配字符串 "aaa123" 中的 a123
如果匹配字符串 "aaa23" 則為 a23 籽暇。
如果匹配字符串 "aaa456123" 則匹配失敗戒悠。
{m,n}? 非貪婪模式舟山,匹配符合的最短的字符串 表達式:a[0-9]{1,4}?23,匹配字符串 "aaa123" 中的 a123 六孵。
如果匹配字符串 "aaa23" 則匹配失敗 幅骄。
如果匹配字符串 "aaa456123" 則為 a456123

匹配邊界

語法 匹配 示例
^ 匹配字符串開頭 表達式:^\d 表示必須以數(shù)字開頭拆座。
表達式:[^abc] 匹配 a, b, c 之外的任意一個字符。
$ 匹配字符串結(jié)尾 表達式:*.com$ 匹配 .com 結(jié)尾的字符串孕索。
\d$表示必須以數(shù)字結(jié)束搞旭。
\A 指定的字符串匹必須出現(xiàn)在開頭 表達式:\Aa,匹配字符串 "aaa123" 中的 a 镇眷。
\Z 指定的字符串匹必須出現(xiàn)在結(jié)尾欠动。如果是存在換行惑申,只匹配到換行前的結(jié)束字符串。 表達式:\d\Z人芽,匹配字符串 "aaa123" 中的 3 碗脊。
\b 匹配一個單詞邊界,但只在單詞開始或結(jié)尾的位置衙伶,即匹配 \w\W 之間害碾。(本身不匹配任何字符) 表達式:\b4慌随,匹配字符串 "aaa123 456" 中的 4
表達式:\b5丸逸,匹配字符串 "aaa123 456" 則為失敗黄刚。
\B 匹配非單詞邊界民效,但不能在詞的開頭或者結(jié)尾,即匹配 [^\b] 业扒。(本身不匹配任何字符) 表達式:\B4程储,匹配字符串 "aaa123 456" 則為失敗。
表達式:\B5摊灭,匹配字符串 "aaa123 456" 中的 5 咏窿。

匹配條件分組

語法 匹配 示例
| 匹配左右任意一個表達式 表達式:a|b,匹配字符串 "aaa123" 中的 a 集嵌。
(ab) 括號中表達式作為一個分組 表達式:(a1),匹配字符串 "aaa123" 中的 a1 怜珍。
表達式:(P|p)ython酥泛,可以匹配 Python 或者 python嫌拣。
(?:exp) 表示非捕獲分組,匹配 pattern 但不獲取匹配結(jié)果捶索。 表達式:([a-z]*)([0-9]*)([a-z]*)腥例,匹配字符串 "aaa123def456" 中的 'aaa', '123', 'def' 酝润。
表達式:(?:[a-z]*)([0-9]*)([a-z]*),匹配字符串 "aaa123def456" 中的 '123', 'def' 构回。
\<number> 引用編號為 number 的分組(規(guī)則)匹配到的字符串 表達式:(\d)def\1捐凭,匹配字符串 "aaa123def321" 中的 3def3 茁肠。
(?P<name>) 給分組起一個別名 name 表達式:(?P<tag>\d)def(?P=tag),匹配字符串 "aaa123def321" 中的 3def3 垦梆。
(?P=name) 引用別名為 name 的分組匹配字符串 表達式:<(?P<tag>\w*)>.*</(?P=tag)>,匹配字符串 <html><h1>www.iHTCboy.com</h1><html> 中的 <h1>www.iHTCboy.com</h1> 印蓖。

預搜索

語法 匹配 示例
(?=exp) 斷言自身出現(xiàn)的位置的后面能匹配表達式 exp赦肃,exp1(?=exp2):查找 exp2 前面的 exp1公浪。 表達式:Windows(?=XP|7|8) 能匹配Windows7 中的 “Windows”欠气,但不能匹配 Windows10 中的“Windows”。
(?!exp) 斷言自身出現(xiàn)的位置的后面不能匹配表達式 exp队塘,exp1(?!exp2):查找后面不是 exp2 的 exp1憔古。 表達式:Windows(?!XP|7|8) 能匹配Windows10 中的“Windows”淋袖,但不能匹配 Windows7 中的“Windows”适贸。
(?<=exp) 斷言自身出現(xiàn)的位置的前面能匹配表達式 exp涝桅,(?<=exp2)exp1:查找 exp2 后面的 exp1冯遂。 表達式:(?<=XP|7|8)Windows 能匹配 7Windows 中的“Windows”蛤肌,但不能匹配 10Windows 中的“Windows”。
(?<!exp) 斷言自身出現(xiàn)的位置的前面不能匹配表達式 exp展东,(?<!=exp2)exp1:查找前面不是 exp2 的 exp1炒俱。 表達式:(?<!XP|7|8)Windows 能匹配 10Windows 中的“Windows”,但不能匹配 7Windows 中的“Windows”砸王。

exp :expression(表達式)

匹配模式

類型 模式 說明
IGNORECASE 忽略大小寫模式 匹配時忽略大小寫谦铃。(正則默認是區(qū)分大小寫的)
SINGLELINE 單行模式 整個文本看作一個字符串,只有一個開頭一個結(jié)尾
MULTILINE 多行模式 每行都是一個字符串瘪菌。在多行模式下控嗜,如果需要僅匹配字符串開始和結(jié)束位置骡显,可以使用 \A 和 \Z

3、Python 正則表達式

如果使用編輯語言來執(zhí)行正則表達式呢壁顶?所有語言都是相通的溜歪,這是記錄了之前使用 Python 的 re 模塊做正則匹配的功能。

compile 和 match 函數(shù)

re.compile 函數(shù)用于編譯正則表達式调衰,生成一個正則表達式( Pattern )對象嚎莉,供 match()沛豌、search() 等函數(shù)使用加派。
re.match 嘗試從字符串的起始位置匹配一個模式芍锦,如果字符串開始不符合正則表達式,就返回 None 饶米。

result = re.match(pattern, string)

等價于

prog = re.compile(pattern)
result = prog.match(string)

注:如果需要多次使用這個正則表達式的話,使用 re.compile() 保存這個正則對象以便復用匹配多個字符串照瘾,可以讓程序更加高效析命。

search 函數(shù)

re.search 掃描整個字符串并返回第一個成功的匹配鹃愤。如果沒有匹配完域,就返回一個 None 吟税。

re.search(pattern, string, flags=0)

示例:

>>> re.search('iHTCboy', 'www.iHTCboy.com')
>>> 
<re.Match object; span=(4, 11), match='iHTCboy'>

我們可以使用 group(num)groups() 匹配對象函數(shù)來獲取匹配表達式肠仪。

>>> searchObj = re.search( r'(.*) are (.*?) .*', "iHTCboy are my nikename)
>>> print(searchObj.group())
>>> print(searchObj.groups())
>>> print(searchObj.group(1))
>>> print(searchObj.group(2))
>>> 
iHTCboy are my nikename
('iHTCboy', 'my')
iHTCboy
my

findall 函數(shù)

re.findall 在字符串中找到正則表達式所匹配的所有子串异旧,并返回一個列表,如果沒有找到匹配的荤崇,則返回空列表天试。

re.findall(pattern, string, flags=0)

string 返回一個不重復的 pattern 的匹配列表然低, string 從左到右進行掃描雳攘,匹配按找到的順序返回吨灭。如果樣式里存在一到多個組刑巧,就返回一個組合列表无畔;就是一個元組的列表(如果樣式里有超過一個組合的話)浑彰≌蓿空匹配也會包含在結(jié)果里。

比如查找字符串中的所有數(shù)字:

>>> result2 = re.findall(r'\d+', 'abc123d4efg567')
>>> 
['123', '4', '567']

查找不是以 4诉濒、7 結(jié)尾的手機號碼(11位)手機號碼:

>>> result2 = re.findall(r'^1\d{9}[0-35-68-9]$', 'xxxxx')
>>> 

finditer 函數(shù)

和 findall 類似未荒,在字符串中找到正則表達式所匹配的所有子串,并把它們作為一個迭代器返回及志。

re.finditer(pattern, string, flags=0)

搜索string片排,返回一個順序訪問每一個匹配結(jié)果(Match對象)的迭代器:

>>> for m in re.finditer(r'\d+', 'abc123d4efg567'):
>>>     print(m.group())
>>>  
123
4
567 

split 函數(shù)

re.split 方法按照能夠匹配的子串將字符串分割后返回列表。

re.split(pattern, string, maxsplit=0, flags=0)

pattern 分開 string 困肩。如果 maxsplit 非零划纽, 最多進行 maxsplit 次分隔, 剩下的字符全部返回到列表的最后一個元素锌畸。

對于規(guī)則的字符串勇劣,比如 abc 我們一般可以用 split 函數(shù)分割,但是如果遇到 a b c 這樣的字符串潭枣,得到的結(jié)果就是 ['a', 'b', '', '', 'c']比默。所以命咐,你可能需要人工來自己再次過濾,而使用正則表達式來處理窜司,就顯示很輕松:

>>> re.split(r'[\s\,]+', 'a,b, c  d')
>>> 
['a', 'b', 'c', 'd']

上面的 [\s\,]+ 表示匹配 \s (空格)和 , 中任意一個至少一次的分割。

對于一個找不到匹配的字符串而言议薪,split 不會對其作出分割产捞。

>>> re.split('a*', 'hello iHTCboy')
>>> 
['hello iHTCboy']

sub 函數(shù)

re.sub 用于替換字符串中的匹配項。

re.sub(pattern, repl, string, count=0, flags=0)

返回通過使用 repl 替換在 string 最左邊非重疊出現(xiàn)的 pattern 而獲得的字符串。 如果樣式?jīng)]有找到衷笋,則不加改變地返回 string。 repl 可以是字符串或函數(shù);如為字符串容客,則其中任何反斜杠轉(zhuǎn)義序列都會被處理。 也就是說供置,\n 會被轉(zhuǎn)換為一個換行符,\r 會被轉(zhuǎn)換為一個回車附,依此類推。

比如電話號碼格式可能帶有空格或者-時挎挖,可以替換為空字符串:

>>> re.sub(r'\D', "", "188-8888-8888")
>>> 
18888888888

repl 參數(shù)可以是一個函數(shù),用于對匹配的內(nèi)容進行更多的邏輯處理:

# 將匹配的數(shù)字乘以 2
>>> def double(matched):
>>>     value = int(matched.group('value'))
>>>     return str(value * 2)
>>>  
>>> re.sub('(?P<value>\d+)', double, 'abc123d4efg567')
>>> 
abc246d8efg1134

總結(jié)

正則表達式的內(nèi)容有非常的多,如果不經(jīng)常使用的話汛闸,可以就會很快忘記。所以别伏,正則其實是不是應(yīng)該記住呢?其實类茂,應(yīng)該是要記住注益,如果記不住厦瓢,要不要緊?其實,是不要緊杉武,因為正則就想查表一下,你如果之前已經(jīng)比較系統(tǒng)的學習過祈搜,忘記了規(guī)則曹铃,看一下本文就大概記起來了秘血。所以忍坷,這就是本文的目的柑肴,總結(jié)性的文章,不需要太多的復雜硕舆,簡單又快捷的總結(jié)。

國慶中秋雙節(jié)快樂凌节!這篇文章應(yīng)該是去年9月就定下來但遲遲沒有動手彪见,現(xiàn)在又過一年了,感嘆生活真快。好好學習,天天快樂~

參考


  • 如有疑問,歡迎在評論區(qū)一起討論!
  • 如有不正確的地方,歡迎指導钥庇!


注:本文首發(fā)于 iHTCboy's blog参咙,如若轉(zhuǎn)載两入,請注來源


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末净宵,一起剝皮案震驚了整個濱河市阻星,隨后出現(xiàn)的幾起案子畦幢,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,013評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件被碗,死亡現(xiàn)場離奇詭異衣迷,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評論 2 382
  • 文/潘曉璐 我一進店門腮敌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人赁咙,你說我怎么就攤上這事凤覆〔橙校” “怎么了?”我有些...
    開封第一講書人閱讀 152,370評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長诫舅。 經(jīng)常有香客問我骚勘,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,168評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘宝踪。我一直安慰自己侨糟,他們只是感情好,可當我...
    茶點故事閱讀 64,153評論 5 371
  • 文/花漫 我一把揭開白布瘩燥。 她就那樣靜靜地躺著秕重,像睡著了一般。 火紅的嫁衣襯著肌膚如雪厉膀。 梳的紋絲不亂的頭發(fā)上溶耘,一...
    開封第一講書人閱讀 48,954評論 1 283
  • 那天二拐,我揣著相機與錄音,去河邊找鬼凳兵。 笑死百新,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 38,271評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼轰豆,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了鲜锚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,916評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后斟珊,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,382評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡富纸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,877評論 2 323
  • 正文 我和宋清朗相戀三年倍宾,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片胜嗓。...
    茶點故事閱讀 37,989評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖钩乍,靈堂內(nèi)的尸體忽然破棺而出辞州,到底是詐尸還是另有隱情,我是刑警寧澤寥粹,帶...
    沈念sama閱讀 33,624評論 4 322
  • 正文 年R本政府宣布变过,位于F島的核電站,受9級特大地震影響涝涤,放射性物質(zhì)發(fā)生泄漏媚狰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,209評論 3 307
  • 文/蒙蒙 一阔拳、第九天 我趴在偏房一處隱蔽的房頂上張望崭孤。 院中可真熱鬧,春花似錦糊肠、人聲如沸辨宠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嗤形。三九已至,卻和暖如春弧圆,著一層夾襖步出監(jiān)牢的瞬間赋兵,已是汗流浹背笔咽。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留霹期,地道東北人叶组。 一個月前我還...
    沈念sama閱讀 45,401評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像经伙,于是被迫代替她去往敵國和親扶叉。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,700評論 2 345