寫代碼時候,不管是爬蟲,還是獲取某些特定的資源,我們需要寫正則表達式。 因為不常用,有些語法生疏。有時明明覺得自己的語法可以,可就是不行。
正則表達式是一種文本模式,包括普通字符(例如,a 到 z 之間的字母)和特殊字符(稱為“元字符”)。 不管是python還是shell,都可以寫正則。
正則表達式基本語法
頭和尾
他們的作用是分別指出一個字符串的開始和結束。例子如下:
"^The":表示所有以"The"開始的字符串("There","The cat"等);
"of despair":表示開始和結尾都是"abc"的字符串——呵呵,只有"abc"自己了;
"notice":表示任何包含"notice"的字符串。
模糊匹配
'.'表示匹配任意的一個字符,相當於一個占位符號。
'',“沒有或更多”
'+',“一次或更多”
'?',“沒有或一次”
下面是幾個例子:
"ab":表示一個字符串有一個a后面跟着零個或若干個b。("a", "ab", "abbb",……);
"ab+":表示一個字符串有一個a后面跟着至少一個b或者更多;
"ab?":表示一個字符串有一個a后面跟着零個或者一個b;
"a?b+$":表示在字符串的末尾有零個或一個a跟着一個或幾個b。
分組和范圍
() 是為了提取匹配的字符串。表達式中有幾個()就有幾個相應的匹配字符串。
[]是定義匹配的字符范圍。比如 [a-zA-Z0-9] 表示相應位置的字符要匹配英文字符和數字。[\s]表示空格或者號。
{}一般用來表示匹配的長度,比如 \s{3} 表示匹配三個空格,\s{1,3}表示匹配一到三個空格。
你也可以使用范圍,用大括號括起,用以表示重復次數的范圍。
"ab{2}":表示一個字符串有一個a跟着2個b("abb");
"ab{2,}":表示一個字符串有一個a跟着至少2個b;
"ab{3,5}":表示一個字符串有一個a跟着3到5個b。
區別:
圓括號()是組,主要應用在限制多選結構的范圍/分組/捕獲文本/環視/特殊模式處理
(abc|bcd|cde),表示這一段是abc、bcd、cde三者之一均可,順序也必須一致。
方括號是單個匹配,字符集/排除字符集/命名字符集
示例:
1、[0-3],表示找到這一個位置上的字符只能是0到3這四個數字,與(abc|bcd|cde)的作用比較類似,但圓括號可以匹配多個連續的字符,而一對方括號只能匹配單個字符
2、[^0-3],表示找到這一個位置上的字符只能是除了0到3之外的所有字符
()內的內容表示的是一個子表達式,()本身不匹配任何東西,也不限制匹配任何東西,只是把括號內的內容作為同一個表達式來處理
[]表示匹配的字符在[]中,並且只能出現一次,並且特殊字符寫在[]會被當成普通字符來匹配
選擇,'¦',表示“或”操作
"hi¦hello":表示一個字符串里有"hi"或者"hello";
"(b¦cd)ef":表示"bef"或"cdef";
"(a¦b)*c":表示一串"a""b"混合的字符串后面跟一個"c";
為了逐字表達,你必須在"^.$()¦*+?{"這些字符前加上轉移字符''。
請注意在方括號中,不需要轉義字符。
元字符及其在正則表達式上下文中的行為:
\ 將下一個字符標記為一個特殊字符、或一個原義字符、或一個后向引用、或一個八進制轉義符。
^ 匹配輸入字符串的開始位置。如果設置了 RegExp 對象的Multiline 屬性,^ 也匹配 '\n' 或 '\r' 之后的位置。也匹配 '\n' 或 '\r' 之前的位置
{n} n 是一個非負整數,匹配確定的n 次。
{n,} n 是一個非負整數,至少匹配n 次。
{n,m} m 和 n 均為非負整數,其中n <= m。最少匹配 n 次且最多匹配 m 次。在逗號和兩個數之間不能有空格。
? 當該字符緊跟在任何一個其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面時,匹配模式是非貪婪的。非貪婪模式盡可能少的匹配所搜索的字符串,而默認的貪婪模式則盡可能多的匹配所搜索的字符串。
. 匹配除 “\n” 之外的任何單個字符。要匹配包括 '\n' 在內的任何字符,請使用象 '[.\n]' 的模式。
(pattern) 匹配pattern 並獲取這一匹配。
(?:pattern) 匹配pattern 但不獲取匹配結果,也就是說這是一個非獲取匹配,不進行存儲供以后使用。
(?=pattern) 正向預查,在任何匹配 pattern 的字符串開始處匹配查找字符串。這是一個非獲取匹配,也就是說,該匹配不需要獲取供以后使用。
(?!pattern) 負向預查,與(?=pattern)作用相反
x|y 匹配 x 或 y。
[xyz] 字符集合。
[^xyz] 負值字符集合。
[a-z] 字符范圍,匹配指定范圍內的任意字符。
[^a-z] 負值字符范圍,匹配任何不在指定范圍內的任意字符。
\b 匹配一個單詞邊界,也就是指單詞和空格間的位置。
\B 匹配非單詞邊界。
\cx 匹配由x指明的控制字符。
\d 匹配一個數字字符。等價於 [0-9]。
\D 匹配一個非數字字符。等價於 [^0-9]。
\f 匹配一個換頁符。等價於 \x0c 和 \cL。
\n 匹配一個換行符。等價於 \x0a 和 \cJ。
\r 匹配一個回車符。等價於 \x0d 和 \cM。
\s 匹配任何空白字符,包括空格、制表符、換頁符等等。等價於[ \f\n\r\t\v]。
\S 匹配任何非空白字符。等價於 [^ \f\n\r\t\v]。
\t 匹配一個制表符。等價於 \x09 和 \cI。
\v 匹配一個垂直制表符。等價於 \x0b 和 \cK。
\w 匹配包括下划線的任何單詞字符。等價於'[A-Za-z0-9_]'。
\W 匹配任何非單詞字符。等價於 '[^A-Za-z0-9_]'。
\xn 匹配 n,其中 n 為十六進制轉義值。十六進制轉義值必須為確定的兩個數字長。
\num 匹配 num,其中num是一個正整數。對所獲取的匹配的引用。
太多了,大概記住就行了。
貪婪與非貪婪
屬於貪婪模式的量詞,也叫做匹配優先量詞,包括:
“{m,n}”、“{m,}”、“?”、“”和“+”。
在一些使用NFA引擎的語言中,在匹配優先量詞后加上“?”,即變成屬於非貪婪模式的量詞,也叫做忽略優先量詞,包括:
“{m,n}?”、“{m,}?”、“??”、“?”和“+?”。
意思是說,跟人性一樣,本性是貪婪的。但是,經過自己的反問,變得不貪婪了。
以下一些例子,來闡明這個
101000011000
1.* 結果:all, 貪婪的,所有匹配
1.? 結果:10,10,11, 非貪婪(最多一個,達到為止)
1.+ 結果:all, 貪婪的,所有匹配
1.*? 結果:非1 1 1 1 , 非貪婪的(點后面0個)
1.+? 結果:10,10,11,非貪婪的(點后面一個)
1.?+ no(不合法)
1.?* no (不合法)
1.*+ no(不合法)
1.+* no (不合法)
如果對自己寫的表達式沒有信心,可以找個工具檢測以下。
網上很多工具,如:
檢驗: http://tool.oschina.net/regex/#
來檢驗一下,比如我們要匹配email地址
E-mail地址:我寫的,\w+@\w+.\w+
雖然不是特別精確,但是基本功能能夠滿足了。
手機號碼:^((\d2,3)|(\d{3}-))?13\d{9}$
[0-9]{11}
1[0-9]{10}
\d{11}
35、IP:
my: (\d+){1,3}.(\d+){1,3}.(\d+){1,3}.(\d+){1,3}


正則表達式也會有精度的。一般我們要把其特征點找出來,后面的就好辦了。
鏈接:https://zhuanlan.zhihu.com/p/55458429