元字符 | 功能 |
---|---|
^ |
以什麼開頭 |
$ |
以什麼結尾 |
. |
匹配一個字符 |
* |
匹配0個或多個 |
[] |
匹配集合中的 |
[x-y] |
匹配集合範圍內的 |
[^ ] |
匹配不在集合中的 |
\ |
轉義 |
元字符 | 功能 | 實例 | 怎麼匹配 |
---|---|---|---|
\< |
以什麼開頭 | '\<love' |
匹配以love開頭的全部行 |
\> |
以什麼結尾 | 'love\>' |
匹配love結尾的全部行 |
\(..\) |
標籤匹配之後使用的字符 | '\(love\)able \1er' |
用位置\1\2引導前面作好的標籤,最大支持9個 |
x\{m\} or x\{m,\} or x\{m,n\} |
重複字符x,m次,至少m次,至少m且不超過n次 | o\{5,10\} |
o 字符重複5到10次的行 |
元字符 | 說明 |
---|---|
+ |
重複前一個字符一個或一個以上 |
? |
0個或者一個字符 |
` | ` |
() |
分組過濾匹配 |
一、^html
^表示錨定行首,可能你們不太明白這個錨定行首是什麼意思,不要緊,看一個例子就能立刻知道怎麼回事了。如今咱們須要在regular.txt文件中找出行首是guo的行。linux
能夠看出,儘管原始文件的第二、四、8行都含有guo,可是它們都不是出如今行首,所以不會匹配,匹配上行的都是行首爲guo的行。這就是前面所說的錨定行首的意思。是否是一下就理解了正則表達式
$ grep '^love' re-file love, how much I adore you. Do you know
$ grep 'love$' re-file clover. Did you see them? I can only hope love.
l
開頭,中間包含兩個字符,結尾是e
的全部行$ grep 'l..e' re-file I had a lovely time on our little picnic. love, how much I adore you. Do you know the extent of my love? Oh, by the way, I think I lost my gloves somewhere out in that field of clover. Did you see them? I can only hope love. is forever. I live for you. It's hard to get back in the
A-Z
的字母,其次是ove
$ grep '[A-Z]ove' re-file Lovers were all around us. It is springtime. Oh
A-Z
範圍內的任何字符行,全部的小寫字符$ grep '[^A-Z]' re-file I had a lovely time on our little picnic. Lovers were all around us. It is springtime. Oh love, how much I adore you. Do you know the extent of my love? Oh, by the way, I think I lost my gloves somewhere out in that field of clover. Did you see them? I can only hope love. is forever. I live for you. It's hard to get back in the groove.
$ grep '^$' re-file
$ grep '.*' re-file I had a lovely time on our little picnic. Lovers were all around us. It is springtime. Oh love, how much I adore you. Do you know the extent of my love? Oh, by the way, I think I lost my gloves somewhere out in that field of clover. Did you see them? I can only hope love. is forever. I live for you. It's hard to get back in the groove.
二、$spring
$表示錨定行尾, 前面已經知道了錨定行首 ,那麼錨定行尾不用說也應該知道怎麼回事了吧,對,$表示的出如今此字符前面的內容都必須出如今行尾纔會匹配,好比說須要在regular.txt文件中找出行尾是guo的行。 express
三、\< 或者 \bide
\< 或者 \b 用來錨定詞首,其後面出現的內容必須做爲單詞首部出現纔會匹配,如今讓咱們在regular.txt文件中找出詞首是guo的行。 咱們能夠這麼作。測試
love.
$ grep 'love\.' re-file clover. Did you see them? I can only hope love.
o
字符重複2到4次$ grep 'o\{2,4\}' re-file groove.
o
字符至少2次$ grep 'o\{2,\}' re-file groove.
0
字符最多2次$ grep 'o\{,2\}' re-file I had a lovely time on our little picnic. Lovers were all around us. It is springtime. Oh love, how much I adore you. Do you know the extent of my love? Oh, by the way, I think I lost my gloves somewhere out in that field of clover. Did you see them? I can only hope love. is forever. I live for you. It's hard to get back in the groove.
$ egrep "go+d" linux.txt Linux is a good god assdxw bcvnbvbjk gooodfs awrerdxxhkl good
ansheng@Ubuntu:/tmp$ egrep "go?d" linux.txt god assdxw bcvnbvbjk gdsystem awxxxx
$ egrep "gd|good" linux.txt Linux is a good gdsystem awxxxx good
$ egrep "g(la|oo)d" linux.txt Linux is a good glad good
四、\>或者 \b spa
\> 或者 \b (對,你沒看錯,\b既能錨定詞首 ,也能錨定詞尾 )用來錨定詞尾,其前面出現的內容必須做爲單詞尾部出現纔會匹配,好了,如今讓咱們在regular.txt文件中找出詞尾部是guo的行。 咱們能夠這麼作。 3d
五、\Bcode
\B 是用來匹配非單詞邊界的,和\b做用相反,什麼意思了,仍是用例子來講明一切吧。找出regular文件中 guo不出如今詞尾的行,其實這中間包含兩個條件:其一是匹配的行要包含guo;其二是guo不能出如今行尾。
一個regular_1.txt文件,讓你找出含有連續2個a的行,應該怎麼查找?這還不簡單嘛,cat regular_1.txt | grep "aa" ;很好,如今換成另外一個問題:找出含有連續100個a的行 。難道在命令中連續寫上100個a ?顯然太累人了。
原始文件的內容
一、\{m\}
\{m\} 表示匹配前面字符m次,也就是說前面字符出現m次的行會被匹配,好了,實驗一把吧,查找regular_1.txt 文件中a連續出現2次的行。
只要是連續出現了2次a以上的行都會被匹配上,這個世界究竟怎麼了?我明明只是想要連續出現兩次a的行就能夠了,幹嗎給我返回這麼多。其實很簡單。連續3個a就已經包含了連續2個a,確定能匹配上。再看看第5行,連續4個a包含了2次連續2個a,至關於第5行匹配上了2次。
如今咱們能夠很輕鬆的寫出下面這樣的命令來找出文件中含有連續100個a的行 :
cat regular_1.txt | grep "a\{100\}"
二、\{m,\}
\{m,\} 至少匹配前面字符m次,好了, 咱們再來查找regular_1.txt 文件中a連續 出現2次以上的行。
仔細看看第四、6行,仍是有些許不一樣的,以第3行爲例,\{2\}形式匹配的時候第3行被匹配上是由於連續包含了2個a被匹配上,所以輸出中最後的a沒有顏色;而\{2,\}形式第3行被匹配上是由於連續包含了3個a才被匹配上。果相同但因卻不同。
三、\{m,n\}
\{m,n\} 匹配前面字符 最少m次,最多m次均可以,好了, 咱們再來查找regular_1.txt 文件中a連續 出現2次到3次的行。
至於第6行含有連續5個a爲何能被匹配上,經過前面的分析我想你們應該知道緣由吧。
四、*
*表示其前面的字符連續出現任意次,這個任意固然包括0次了,也包括屢次,好了,如今咱們用*來匹配測試下。
能夠看出,原始文件中不管有多少個a都被匹配出,儘管第1行不含a字符,但仍是匹配出來了。
五、\?
\?表示其前面的字符連續出現0次或者1次,下面咱們用它來匹配regular_1.txt文件中出現0次或者1次的行。
看到上面的結果嗎,居然和*匹配的結果是同樣的,儘管結果同樣,可是匹配的原理是不一樣的。以第3行爲例,若是使用*匹配,則第3行是以由於其連續含有2個a被匹配上的;而若是是以\?匹配,則第3行被匹配上是由於先匹配了上1個a,再匹配上後面的a,至關於匹配上了2次。因此有時候看事務是不能只看表面的。
六、\+
\+ 表示其前面的字符連續出現1次或者屢次,也就是說,\+前面的字符至少要連續出現一次才能匹配上。若是咱們須要查找文件中出現過a字符的行,咱們可使用下面的命令。
實驗用的文件
一、[[: :]]系列
這是一組形式類似的正則,主要由如下正則組成
看上面的表格,每一個正則所表達的意義已經很清楚了,至於具體怎麼用,仍是舉幾個例子來講明。
下圖中的命令是查找regular_2.txt文件中a後面是任意數字的行,從輸出看,確實只有a後面是數字的行纔會被匹配。
再舉個例子,此次是查找regular_2.txt文件中a後面是標點符號的行,看到沒,用[[:punct:]]就能達到目的了。是否是很簡單,還有其它幾個正則,你們有興趣能夠本身在環境上試試,這裏就不一一舉例了
二、[ ]
[]表示匹配指定範圍內的任意單個單詞。這樣說可能仍是不太容易理解,仍是用實例說明一切吧,如今來找出文件regular_2.txt 中a後面緊跟b或者緊跟c或者緊跟^的行。
[]中還支持用-鏈接表示匹配一個範圍內的一個字符,好比說[A-Z]就等價於[[:upper:]],[0-9]等價於[[:lower:]]等等。
三、^
看過前面文章的同窗可能會以爲詫異,^ 在位置錨定那篇文章中不是已經講過它的做用是用來錨定行首嗎?怎麼這裏又出現了。這是由於^和[ ]結合能表達兩種含義。
^放在[]外表示匹配行首出現[]中字符的行,也就是咱們前面說的錨定行首;而^放在[]內表示「排除、非」的意思,即表示匹配指定範圍外的任意單個單詞。
若是這樣描述仍是有點抽象,仍是用例子來講明一切吧,^表示行首錨定的用法前面文章已經說過了這裏就再也不舉例了,這裏咱們來實驗下^放在[ ]中的用法,如今來查找regular_2.txt文件中a後面不含字母(包括大小寫字母)的行。
四、.
在正則表達式中,.表示匹配任意單個字符(換行符除外),範例以下:找出文件regular_2.txt 中字符a與字符d之間含有任意一個字符的行。能夠看出,只要
a和d之間有一個字符,無論是什麼字符都匹配上了。
實驗所用的文件
一、\( \)
在講分組以前,仍是先一塊兒回顧下匹配指定次數的正則,如"\{2\} "表示匹配到其前面的字符連續出現2次的行,好比說,咱們能夠用"qin\{2\}"將regular_3.txt文件的第4行qinn li匹配到。
可是,若是咱們想要匹配連續出現2次qin的行了?單純的使用"\{2\} " 就無能爲力了,這時候就須要用到分組了,在正則表達式中,\( \)表示分組,所謂的分組就是把\( \) 中出現的內容當作一個總體。
好了,如今能夠找出regular_3.txt 文件連續出現2次qin的行了 ,沒錯,\(qin\)\{2\}就是將qin當作一個總體,再和後面的\{2\} 結合起來表示匹配qin兩次,就是這麼簡單。
分組還能夠嵌套,這又是什麼意思了。看下面的例子。這個表達式看起來很複雜,咱們拆開分析相對來講會容易理解些:黃色部分的兩側是\( \),所以須要將其做爲一個總體和後面的\{2\} 結合起來就是黃色部分出現2次的行被匹配。
好了,那麼黃色部分是又是什麼了,能夠看出,黃色部份內部的正則爲ab\(ef\)\{2\},這個正則應該不難看出它表示的是abefef吧。
所以,能夠分析出整個表達式\(ab\(ef\)\{2\}\)\{2\}就是匹配abefef 出現2次的行。
二、\n
咱們如今能夠介紹後向引用了,後向引用是創建在分組的前提上的,這也是爲何咱們先講分組的緣由。
在一個含有分組的正則表達式中,默認狀況下,每一個分組會自動擁有一個組號(從左向右,以分組的左括號爲標誌,第一個出現的分組的組號爲1,第二個爲2,以此類推)後向引用用於重複搜索前面某個分組匹配的文本。例如,\1 表明此處須要再次匹配分組1 的內容。
如今有個小任務,是須要將原始文件的第1行和第6行匹配出。也就說匹配出li先後單詞相同的兩行。
很多人會寫出下面的式子,可是從輸出看來,結果並不符合要求,由於第二行li 的先後單詞不同,可是也匹配上了。
這時候,後向引用就能派上用途了。看到沒,表達式\(...\) li \1含有一個分組\(...\),這個分組表示匹配任意3個字符,那麼表達式後面的\1就表示\(...\) 匹配到什麼,這裏須要再匹配一次。
所以,若是經過\(...\) 匹配上了qin,那麼在li後面也須要再匹配到qin才能匹配上該行,所以第2行不會匹配上,第1行能匹配上;若是經過\(...\) 匹配上了qzz,那麼在li後面也須要再匹配到qzz才能匹配上 該行,所以第6行能匹配上 。
三、\
\在正則表達式中表示轉義,還記得咱們前面介紹過的字符 .嗎,在正則表達式中,這些字符有特殊含義,好比說 . 表示匹配任意字符。那若是想要正則表達式就匹配文件中的.自己了,這時候就須要轉義字符\了。以下所示,注意正則表達式中有無轉義字符\所匹配結果的區別。
再舉個例子,若是要匹配regular_4.txt 文件中含有\的行,應該怎麼辦了,很簡單,只要在前面再加一個\就行了,以下。
實驗所用的文件
一、{ }、()、+、?、
其實,擴展正則表達式基本正則表達式90%的用法是一摸同樣的,只是有那麼幾個符號有區別,這幾個符號就是{ }、()、+、?,分別對應基本正則表達式中的\{ \}、\(\)、\+、\? ,是否是以爲擴展正則表達式方便多了。
要使得grep將正則表達式中的符號當作擴展表達式去理解,須要用到-E選項,以下示例表達式就是利用擴展正則表達式 {}匹配文件中qi後面出現2次字符n的行,其對應基本表達式:
cat regular_3.txt | grep -n --color "qin\{2\}"
二、|
在擴展正則表達式中,還有一個很經常使用的符號 | ,它表示或,這是基本正則表達式所沒有的,這個符號一般會和分組結合在一塊兒用,下面的例子很清楚的告訴咱們 | 的用法
那麼若是 | 不和分組結合用,會有什麼區別了?仍是看例子
很明顯,| 有沒有和分組一塊兒用,區別很大,從上面的匹配結果很容易看出,"(n|z)$" 表示匹配以n結尾或者以z結尾的行;而"n|z$"則表示匹配以z結尾或者含有n的行。也就是說,若是不用分組,後面的$不會做用在前面的字符n上。
三、總結
擴展正則表達式就總結完了,多,有了前面基本正則表達式的基礎,擴展正則表達式就是這麼簡單。好了,如今整個正則表達式的總結已經完了,基本上你們在工做中能用到的也就差很少這些了,最後你們一塊兒思考一個綜合性的正則表達式問題吧。
給出一個測試文件,找出文件中的郵箱地址,要解決這個問題,首先得知道什麼是合法的郵箱地址,在網上搜了個關於合法郵箱地址的條件,懶得打字,就截圖過來了。
下面是測試文件以及相應的答案。
一、校驗密碼強度
密碼的強度必須包含大小寫字母和數字的組合,不能使用特殊字符,長度在8-10之間
^(?=.\\d)(?=.[a-z])(?=.*[A-Z]).{8,10}$
二、校驗中文
字符串只能是中文
^[\\u4e00-\\u9fa5]{0,}$
三、由數字,26個英文字母或下劃線組成的字符串
^\\w+$
四、校驗E-Mail 地址
[\\w!#$%&'+/=?^_`{|}~-]+(?:\.[\\w!#$%&'+/=?^_`{|}~-]+)@(?:[\\w](?:[\\w-][\\w])?\.)+\\w?
五、校驗身份證號碼
15位:
^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$
18位:
^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}([0-9]|X)$
六、校驗日期
「yyyy-mm-dd「 格式的日期校驗,已考慮平閏年
^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$
七、校驗金額
金額校驗,精確到2位小數
^[0-9]+(.[0-9]{2})?$
八、校驗手機號
下面是國內 1三、1五、18開頭的手機號正則表達式
^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\\d{8}$
九、判斷IE的版本
^.MSIE 5-8?(?!.Trident\\/[5-9]\.0).*$
十、校驗IP-v4地址
\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b
十一、校驗IP-v6地址
(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))
十二、檢查URL的前綴
if (!s.match(/^[a-zA-Z]+:\\/\\//)){
s = 'http://' + s;}
1三、提取URL連接
^(f|ht){1}(tp|tps):\\/\\/([\\w-]+\.)+[\\w-]+(\\/[\\w- ./?%&=]*)?
1四、文件路徑及擴展名校驗
^([a-zA-Z]\\:|\\\)\\\([^\\\]+\\\)[^\\/:?"<>|]+\.txt(l)?$
1五、提取Color Hex Codes
^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$
1六、提取網頁圖片
\\< [img][^\\\\>][src] = [\\"\\']{0,1}([^\\"\\'\\ >]*)
1七、提取頁面超連接
(<a\\s(?!.\\brel=)[^>])(href="https?:\\/\\/)((?!(?:(?:www\.)?'.implode('|(?:www\.)?', $follow_list).'))[^"]+)"((?!.\\brel=)[^>])(?:[^>])>
1八、查找CSS屬性
^\\s[a-zA-Z\-]+\\s[:]{1}\\s[a-zA-Z0-9\\s.#]+[;]{1}
1九、抽取註釋
<!--(.*?)-->
20、匹配HTML標籤
<\\/?\\w+((\\s+\\w+(\\s=\\s(?:".?"|'.?'|[\\^'">\\s]+))?)+\\s|\\s)\\/?>
轉載來源 :碼農有道
https://mp.weixin.qq.com/s/HGSGtMfepNImuwIwVxlwSw
https://mp.weixin.qq.com/s/ghJGV37LVuDydFMQzOy66w
https://mp.weixin.qq.com/s/DOJJtVTwjcQQAz9Km-YE4Q
https://mp.weixin.qq.com/s/Om7YwN84IgohO-orFPUE6g
https://mp.weixin.qq.com/s/1dXYdlPlx9eC8BKg9FYr4Q
https://blog.ansheng.me/article/examples-of-linux-regular-expressions
https://www.qdfuns.com/article/26351/5cc47c5a56c75e45b148a75f0cca536e.html