正則表達式(regular expression)描述了 一種字符串匹配的模式(pattern),可以用來檢查一個串是否含有某種子串、將匹配的子串替換或者從某個串中取出符合某個條件的子串等腕扶。
正則表達式是由普通字符(例如字符 a 到 z)以及特殊字符(稱為"元字符")組成的文字模式
https://www.runoob.com/regexp/regexp-syntax.html
普通字符
普通字符包括沒有顯式指定為元字符的所有可打印和不可打印字符免胃。這包括所有大寫和小寫字母涩禀、所有數(shù)字才睹、所有標點符號和一些其他符號。
字符描述實例
[ABC]匹配?[...]?中的所有字符淳梦,例如?[aeiou]?匹配字符串 "google runoob taobao" 中所有的 e o u a 字母析砸。
[^ABC]匹配除了?[...]?中字符的所有字符,例如?[^aeiou]?匹配字符串 "google runoob taobao" 中除了 e o u a 字母的所有字母爆袍。
[A-Z][A-Z] 表示一個區(qū)間首繁,匹配所有大寫字母作郭,[a-z] 表示所有小寫字母。
.匹配除換行符(\n弦疮、\r)之外的任何單個字符夹攒,相等于 [^\n\r]。
[\s\S]匹配所有胁塞。\s 是匹配所有空白符芹助,包括換行,\S 非空白符闲先,不包括換行。
\w匹配字母无蜂、數(shù)字伺糠、下劃線。等價于 [A-Za-z0-9_]
字符描述
\cx匹配由x指明的控制字符斥季。例如训桶, \cM 匹配一個 Control-M 或回車符。x 的值必須為 A-Z 或 a-z 之一酣倾。否則舵揭,將 c 視為一個原義的 'c' 字符。
\f匹配一個換頁符躁锡。等價于 \x0c 和 \cL午绳。
\n匹配一個換行符。等價于 \x0a 和 \cJ映之。
\r匹配一個回車符拦焚。等價于 \x0d 和 \cM。
\s匹配任何空白字符杠输,包括空格赎败、制表符、換頁符等等蠢甲。等價于 [ \f\n\r\t\v]僵刮。注意 Unicode 正則表達式會匹配全角空格符。
\S匹配任何非空白字符鹦牛。等價于 [^ \f\n\r\t\v]搞糕。
\t匹配一個制表符。等價于 \x09 和 \cI能岩。
\v匹配一個垂直制表符寞宫。等價于 \x0b 和 \cK。
特殊字符
所謂特殊字符拉鹃,就是一些有特殊含義的字符辈赋,如上面說的?runoo*b?中的?*鲫忍,簡單的說就是表示任何字符串的意思。如果要查找字符串中的?*?符號钥屈,則需要對?*?進行轉義悟民,即在其前加一個?\,runo\*ob?匹配字符串?runo*ob篷就。
許多元字符要求在試圖匹配它們時特別對待射亏。若要匹配這些特殊字符,必須首先使字符"轉義"竭业,即智润,將反斜杠字符\?放在它們前面。下表列出了正則表達式中的特殊字符:
特別字符描述
$匹配輸入字符串的結尾位置未辆。如果設置了 RegExp 對象的 Multiline 屬性窟绷,則 $ 也匹配 '\n' 或 '\r'。要匹配 $ 字符本身咐柜,請使用 \$兼蜈。
( )標記一個子表達式的開始和結束位置。子表達式可以獲取供以后使用拙友。要匹配這些字符为狸,請使用 \( 和 \)。
*匹配前面的子表達式零次或多次遗契。要匹配 * 字符辐棒,請使用 \*。
+匹配前面的子表達式一次或多次牍蜂。要匹配 + 字符涉瘾,請使用 \+。
.匹配除換行符 \n 之外的任何單字符捷兰。要匹配 . 立叛,請使用 \. 。
[標記一個中括號表達式的開始贡茅。要匹配 [秘蛇,請使用 \[。
?匹配前面的子表達式零次或一次顶考,或指明一個非貪婪限定符赁还。要匹配 ? 字符,請使用 \?驹沿。
\將下一個字符標記為或特殊字符艘策、或原義字符、或向后引用渊季、或八進制轉義符朋蔫。例如罚渐, 'n' 匹配字符 'n'。'\n' 匹配換行符驯妄。序列 '\\' 匹配 "\"荷并,而 '\(' 則匹配 "("。
^匹配輸入字符串的開始位置青扔,除非在方括號表達式中使用源织,當該符號在方括號表達式中使用時,表示不接受該方括號表達式中的字符集合微猖。要匹配 ^ 字符本身谈息,請使用 \^。
{標記限定符表達式的開始凛剥。要匹配 {黎茎,請使用 \{。
|指明兩項之間的一個選擇当悔。要匹配 |,請使用 \|踢代。
限定符
限定符用來指定正則表達式的一個給定組件必須要出現(xiàn)多少次才能滿足匹配盲憎。有?*?或?+?或???或?{n}?或?{n,}?或?{n,m}?共6種。
正則表達式的限定符有:
字符描述
*匹配前面的子表達式零次或多次胳挎。例如饼疙,zo* 能匹配 "z" 以及 "zoo"。* 等價于{0,}慕爬。
+匹配前面的子表達式一次或多次窑眯。例如,'zo+' 能匹配 "zo" 以及 "zoo"医窿,但不能匹配 "z"磅甩。+ 等價于 {1,}。
?匹配前面的子表達式零次或一次姥卢。例如卷要,"do(es)?" 可以匹配 "do" 、 "does" 中的 "does" 独榴、 "doxy" 中的 "do" 僧叉。? 等價于 {0,1}。
{n}n 是一個非負整數(shù)棺榔。匹配確定的 n 次瓶堕。例如,'o{2}' 不能匹配 "Bob" 中的 'o'症歇,但是能匹配 "food" 中的兩個 o郎笆。
{n,}n 是一個非負整數(shù)谭梗。至少匹配n 次。例如题画,'o{2,}' 不能匹配 "Bob" 中的 'o'默辨,但能匹配 "foooood" 中的所有 o。'o{1,}' 等價于 'o+'苍息。'o{0,}' 則等價于 'o*'缩幸。
{n,m}m 和 n 均為非負整數(shù),其中n <= m竞思。最少匹配 n 次且最多匹配 m 次表谊。例如,"o{1,3}" 將匹配 "fooooood" 中的前三個 o盖喷。'o{0,1}' 等價于 'o?'爆办。請注意在逗號和兩個數(shù)之間不能有空格。
通過在?*课梳、+?或???限定符之后放置??距辆,該表達式從"貪婪"表達式轉換為"非貪婪"表達式或者最小匹配。
定位符
定位符使您能夠將正則表達式固定到行首或行尾暮刃。它們還使您能夠創(chuàng)建這樣的正則表達式跨算,這些正則表達式出現(xiàn)在一個單詞內、在一個單詞的開頭或者一個單詞的結尾椭懊。
定位符用來描述字符串或單詞的邊界诸蚕,^?和?$?分別指字符串的開始與結束,\b?描述單詞的前或后邊界氧猬,\B?表示非單詞邊界背犯。
正則表達式的定位符有:
字符描述
^匹配輸入字符串開始的位置。如果設置了 RegExp 對象的 Multiline 屬性盅抚,^ 還會與 \n 或 \r 之后的位置匹配漠魏。
$匹配輸入字符串結尾的位置。如果設置了 RegExp 對象的 Multiline 屬性妄均,$ 還會與 \n 或 \r 之前的位置匹配蛉幸。
\b匹配一個單詞邊界,即字與空格間的位置丛晦。
\B非單詞邊界匹配奕纫。
注意:不能將限定符與定位符一起使用。由于在緊靠換行或者單詞邊界的前面或后面不能有一個以上位置烫沙,因此不允許諸如?^*?之類的表達式匹层。
若要匹配一行文本開始處的文本,請在正則表達式的開始使用?^?字符。不要將?^?的這種用法與中括號表達式內的用法混淆升筏。
若要匹配一行文本的結束處的文本撑柔,請在正則表達式的結束處使用?$?字符。
若要在搜索章節(jié)標題時使用定位點您访,下面的正則表達式匹配一個章節(jié)標題铅忿,該標題只包含兩個尾隨數(shù)字,并且出現(xiàn)在行首:
正則表達式 -?運算符優(yōu)先級
正則表達式從左到右進行計算灵汪,并遵循優(yōu)先級順序檀训,這與算術表達式非常類似。
相同優(yōu)先級的從左到右進行運算享言,不同優(yōu)先級的運算先高后低峻凫。下表從最高到最低說明了各種正則表達式運算符的優(yōu)先級順序:
運算符描述
\轉義符
(), (?:), (?=), []圓括號和方括號
*, +, ?, {n}, {n,}, {n,m}限定符
^, $, \任何元字符、任何字符定位點和序列(即:位置和順序)
|替換览露,"或"操作
字符具有高于替換運算符的優(yōu)先級荧琼,使得"m|food"匹配"m"或"food"。若要匹配"mood"或"food"差牛,請使用括號創(chuàng)建子表達式命锄,從而產生"(m|f)ood"。
案例
正則表達式描述
hello匹配 {hello}
gray|grey匹配 {gray, grey}
gr(a|e)y匹配 {gray, grey}
gr[ae]y匹配 {gray, grey}
b[aeiou]bble匹配 {babble, bebble, bibble, bobble, bubble}
[b-chm-pP]at|ot匹配 {bat, cat, hat, mat, nat, oat, pat, Pat, ot}
colou?r匹配 {color, colour}
rege(x(es)?|xps?)匹配 {regex, regexes, regexp, regexps}
go*gle匹配 {ggle, gogle, google, gooogle, goooogle, ...}
go+gle匹配 {gogle, google, gooogle, goooogle, ...}
g(oog)+le匹配 {google, googoogle, googoogoogle, googoogoogoogle, ...}
z{3}匹配 {zzz}
z{3,6}匹配 {zzz, zzzz, zzzzz, zzzzzz}
z{3,}匹配 {zzz, zzzz, zzzzz, ...}
[Bb]rainf\*\*k匹配 {Brainf**k, brainf**k}
\d匹配 {0,1,2,3,4,5,6,7,8,9}
1\d{10}匹配 11 個數(shù)字偏化,以 1 開頭
[2-9]|[12]\d|3[0-6]匹配 2 到 36 范圍內的整數(shù)
Hello\nworld匹配 Hello 后跟換行符脐恩,后跟 world
\d+(\.\d\d)?包含一個正整數(shù)或包含兩位小數(shù)位的浮點數(shù)。
[^*@#]排除 *夹孔、@ 、# 三個特色符號
//[^\r\n]*[\r\n]匹配?//?開頭的注釋
^dog匹配以 "dog" 開始
dog$匹配以 "dog" 結尾
^dog$is exactly "dog"
常用正則表達式
一析孽、校驗數(shù)字的表達式
數(shù)字:^[0-9]*$
n位的數(shù)字:^\d{n}$
至少n位的數(shù)字:^\d{n,}$
m-n位的數(shù)字:^\d{m,n}$
零和非零開頭的數(shù)字:^(0|[1-9][0-9]*)$
非零開頭的最多帶兩位小數(shù)的數(shù)字:^([1-9][0-9]*)+(\.[0-9]{1,2})?$
帶1-2位小數(shù)的正數(shù)或負數(shù):^(\-)?\d+(\.\d{1,2})$
正數(shù)搭伤、負數(shù)、和小數(shù):^(\-|\+)?\d+(\.\d+)?$
有兩位小數(shù)的正實數(shù):^[0-9]+(\.[0-9]{2})?$
有1~3位小數(shù)的正實數(shù):^[0-9]+(\.[0-9]{1,3})?$
非零的正整數(shù):^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$
非零的負整數(shù):^\-[1-9][]0-9"*$ 或 ^-[1-9]\d*$
非負整數(shù):^\d+$ 或 ^[1-9]\d*|0$
非正整數(shù):^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$
非負浮點數(shù):^\d+(\.\d+)?$ 或 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
非正浮點數(shù):^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 或 ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
正浮點數(shù):^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ 或 ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
負浮點數(shù):^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ 或 ^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$
浮點數(shù):^(-?\d+)(\.\d+)?$ 或 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$
校驗字符的表達式
漢字:^[\u4e00-\u9fa5]{0,}$
英文和數(shù)字:^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
長度為3-20的所有字符:^.{3,20}$
由26個英文字母組成的字符串:^[A-Za-z]+$
由26個大寫英文字母組成的字符串:^[A-Z]+$
由26個小寫英文字母組成的字符串:^[a-z]+$
由數(shù)字和26個英文字母組成的字符串:^[A-Za-z0-9]+$
由數(shù)字袜瞬、26個英文字母或者下劃線組成的字符串:^\w+$ 或 ^\w{3,20}$
中文怜俐、英文、數(shù)字包括下劃線:^[\u4E00-\u9FA5A-Za-z0-9_]+$
中文邓尤、英文拍鲤、數(shù)字但不包括下劃線等符號:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
可以輸入含有^%&',;=?$\"等字符:[^%&',;=?$\x22]+
禁止輸入含有~的字符:[^~]+
三、特殊需求表達式
Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\.?
InternetURL:[a-zA-z]+://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$
手機號碼:^(13[0-9]|14[5|7]|15[0|1|2|3|4|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$
電話號碼("XXX-XXXXXXX"汞扎、"XXXX-XXXXXXXX"季稳、"XXX-XXXXXXX"、"XXX-XXXXXXXX"澈魄、"XXXXXXX"和"XXXXXXXX):^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$
國內電話號碼(0511-4405222景鼠、021-87888822):\d{3}-\d{8}|\d{4}-\d{7}
電話號碼正則表達式(支持手機號碼,3-4位區(qū)號痹扇,7-8位直播號碼铛漓,1-4位分機號):?((\d{11})|^((\d{7,8})|(\d{4}|\d{3})-(\d{7,8})|(\d{4}|\d{3})-(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1})|(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1}))$)
身份證號(15位溯香、18位數(shù)字),最后一位是校驗位浓恶,可能為數(shù)字或字符X:(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)
帳號是否合法(字母開頭玫坛,允許5-16字節(jié),允許字母數(shù)字下劃線):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
密碼(以字母開頭包晰,長度在6~18之間湿镀,只能包含字母、數(shù)字和下劃線):^[a-zA-Z]\w{5,17}$
強密碼(必須包含大小寫字母和數(shù)字的組合杜窄,不能使用特殊字符肠骆,長度在 8-10 之間):^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[a-zA-Z0-9]{8,10}$
強密碼(必須包含大小寫字母和數(shù)字的組合,可以使用特殊字符塞耕,長度在8-10之間):^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$
日期格式:^\d{4}-\d{1,2}-\d{1,2}
一年的12個月(01~09和1~12):^(0?[1-9]|1[0-2])$
一個月的31天(01~09和1~31):^((0?[1-9])|((1|2)[0-9])|30|31)$
錢的輸入格式:
有四種錢的表示形式我們可以接受:"10000.00" 和 "10,000.00", 和沒有 "分" 的 "10000" 和 "10,000":^[1-9][0-9]*$
這表示任意一個不以0開頭的數(shù)字,但是,這也意味著一個字符"0"不通過,所以我們采用下面的形式:^(0|[1-9][0-9]*)$
一個0或者一個不以0開頭的數(shù)字.我們還可以允許開頭有一個負號:^(0|-?[1-9][0-9]*)$
這表示一個0或者一個可能為負的開頭不為0的數(shù)字.讓用戶以0開頭好了.把負號的也去掉,因為錢總不能是負的吧蚀腿。下面我們要加的是說明可能的小數(shù)部分:^[0-9]+(.[0-9]+)?$
必須說明的是,小數(shù)點后面至少應該有1位數(shù),所以"10."是不通過的,但是 "10" 和 "10.2" 是通過的:^[0-9]+(.[0-9]{2})?$
這樣我們規(guī)定小數(shù)點后面必須有兩位,如果你認為太苛刻了,可以這樣:^[0-9]+(.[0-9]{1,2})?$
這樣就允許用戶只寫一位小數(shù).下面我們該考慮數(shù)字中的逗號了,我們可以這樣:^[0-9]{1,3}(,[0-9]{3})*(.[0-9]{1,2})?$
1到3個數(shù)字,后面跟著任意個 逗號+3個數(shù)字,逗號成為可選,而不是必須:^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(.[0-9]{1,2})?$
備注:這就是最終結果了,別忘了"+"可以用"*"替代如果你覺得空字符串也可以接受的話(奇怪,為什么?)最后,別忘了在用函數(shù)時去掉去掉那個反斜杠,一般的錯誤都在這里
xml文件:^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$
中文字符的正則表達式:[\u4e00-\u9fa5]
雙字節(jié)字符:[^\x00-\xff] (包括漢字在內,可以用來計算字符串的長度(一個雙字節(jié)字符長度計2扫外,ASCII字符計1))
空白行的正則表達式:\n\s*\r (可以用來刪除空白行)
HTML標記的正則表達式:<(\S*?)[^>]*>.*?|<.*? /> ( 首尾空白字符的正則表達式:^\s*|\s*$或(^\s*)|(\s*$) (可以用來刪除行首行尾的空白字符(包括空格莉钙、制表符、換頁符等等)筛谚,非常有用的表達式)
騰訊QQ號:[1-9][0-9]{4,} (騰訊QQ號從10000開始)
中國郵政編碼:[1-9]\d{5}(?!\d) (中國郵政編碼為6位數(shù)字)
IPv4地址:((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}
匹配中文:[\u4e00-\u9fa5]
正則表達式實例:
#!/usr/bin/pythonimport re
line = "Cats are smarter than dogs"matchObj = re.match( r'(.*) are (.*?) .*', line, re.M|re.I)if matchObj:????print "matchObj.group() : ", matchObj.group()????print "matchObj.group(1) : ", matchObj.group(1)????print "matchObj.group(2) : ", matchObj.group(2)else:????print "No match!!"
正則表達式:
r'(.*) are (.*?) .*'
解析:
首先磁玉,這是一個字符串,前面的一個?r?表示字符串為非轉義的原始字符串驾讲,讓編譯器忽略反斜杠蚊伞,也就是忽略轉義字符。但是這個字符串里沒有反斜杠吮铭,所以這個?r?可有可無时迫。
?(.*)?第一個匹配分組,.*?代表匹配除換行符之外的所有字符谓晌。
?(.*?)?第二個匹配分組掠拳,.*??后面多個問號,代表非貪婪模式纸肉,也就是說只匹配符合條件的最少字符
?后面的一個?.*?沒有括號包圍溺欧,所以不是分組,匹配效果和第一個一樣柏肪,但是不計入匹配結果中姐刁。
matchObj.group() 等同于 matchObj.group(0),表示匹配到的完整文本字符
matchObj.group(1) 得到第一組匹配結果烦味,也就是(.*)匹配到的
matchObj.group(2) 得到第二組匹配結果龙填,也就是(.*?)匹配到的
因為只有匹配結果中只有兩組,所以如果填 3 時會報錯。
轉化成字典:
import re
s = '1102231990xxxxxxxx'res = re.search('(?P<province>\d{3})(?P<city>\d{3})(?P<born_year>\d{4})',s)print(res.groupdict())
此分組取出結果為:
{'province': '110', 'city': '223', 'born_year': '1990'}