基于Linux下詳解正則表達式(基本正則和擴展正則命令使用實例)

正則表達式

前言

正則表達式應用廣泛,在絕大多數的編程語言都可以完美應用,在Linux中,也有著極大的用處。
使用正則表達式,可以有效的篩選出需要的文本,然后結合相應的支持的工具或語言,完成任務需求。
在本篇博客中,我們使用grep/egrep來完成對正則表達式的調用,其實也可以使用sed等工具,但是sed的使用極大的需要正則表達式,為了在后面sed篇的書寫,就只能這樣排序了,有需要的朋友可以把這兩篇一起來看。

正則表達式的類型

正則表達式可以使用正則表達式引擎實現,正則表達式引擎是解釋正則表達式模式并使用這些模式匹配文本的基礎軟件。
在Linux中,常用的正則表達式有:

  • POSIX 基本正則表達式(BRE)引擎
  • POSIX 擴展正則表達式(BRE)引擎

基本正則表達式的基本使用

環境文本準備

[root@service99 ~]# mkdir /opt/regular
[root@service99 ~]# cd /opt/regular
[root@service99 regular]# pwd
/opt/regular
[root@service99 regular]# cp /etc/passwd temp_passwd

純文本

純文本可以完全匹配對應的單詞,需要注意的有正則表達式模式嚴格區分大小寫

//grep --color 主要是可以將匹配到的文本高亮顯示,這樣便于觀察效果
[root@service99 regular]# grep --color "root" temp_passwd 
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

在正則表達式中,不必局限于完整的單詞,所定義的文本出現在數據流的任意位置,正則表達式都將匹配。

[root@service99 regular]# ifconfig eth1  | grep --color "add"
eth1      Link encap:Ethernet  HWaddr 54:52:01:01:99:02  
          inet addr:192.168.2.99  Bcast:192.168.2.255  Mask:255.255.255.0
          inet6 addr: fe80::5652:1ff:fe01:9902/64 Scope:Link

當然也不必局限于單獨的單詞,也可以在文本字符串中出現空格和數字。

[root@service99 regular]# echo "This is line number 1" | grep --color "ber 1"
This is line number 1

特殊字符

在正則表達式模式中使用文本字符串時,有一個問題需要注意。
在正則表達式中定義文本字符串時有幾個例外,正則表達式賦予了它們特殊的含義,如果在文本中使用這些特殊字符,有可能得不到預期的效果。
正則表達式認可的特殊字符:

.*[]^${}+?|()

如果想要使用這些特殊字符作為普通的文本字符,就需要轉義(escape)它,即是在該字符前添加一個特殊字符,向正則表達式引擎說明:它應該將下一個字符解釋為普通文本字符。
實現該功能的特殊字符是:“\”反斜杠字符

[root@service99 regular]# echo "This cat is $4.99"  //雙引號不會屏蔽特殊符號,所以系統會讀取變量4.99的值,然而當前系統并沒有該變量,就顯示為空    
This cat is .99
[root@service99 regular]# echo "This cat is \$4.99" //使用"\"轉義$
This cat is $4.99
[root@service99 regular]# echo 'This cat is \$4.99' //單引號屏蔽元字符$
This cat is \$4.99
[root@service99 regular]# echo 'This cat is $4.99'  
This cat is $4.99
[root@service99 regular]# cat price.txt 
This price is $4.99
hello,world!
$5.00
#$#$
This is "\".
[root@service99 regular]# grep --color '\\' price.txt 
This is "\".

定位符

從頭開始

脫字符(^)尖角號定義從數據流中文本行開頭開始的模式。

[root@service99 regular]# grep --color '^h' price.txt   //以字母h開頭的行
hello,world!
[root@service99 regular]# grep --color '^$' price.txt   //無輸出結果,由于沒有屏蔽特殊含義
[root@service99 regular]# grep --color '^\$' price.txt  //以$符號開頭的行
$5.00
[root@service99 regular]# echo "This is ^ test. " >> price.txt 
[root@service99 regular]# cat price.txt 
This price is $4.99
hello,world!
$5.00
#$#$
This is "\".
This is ^ test. 
[root@service99 regular]# grep --color '^' price.txt  //直接使用會顯示所有的內容
This price is $4.99
hello,world!
$5.00
#$#$
This is "\".
This is ^ test. 
[root@service99 regular]# grep --color '\^' price.txt //單獨使用,并在最前面時需要屏蔽
This is ^ test. 
[root@service99 regular]# grep --color 'is ^' price.txt //符號不在最前面時,無需屏蔽,直接使用即可
This is ^ test. 

查找結尾

美元符號$特殊字符定義結尾定位,在文本模式之后添加這個特殊字符表示數據行必須以此文本模式結束。

[root@service99 regular]# grep --color '\.$' price.txt  //“.”在正則表達式中也有特殊含義,請屏蔽,具體的請往下看
This is "\".
[root@service99 regular]# grep --color '\. $' price.txt  //由于我在輸入的時候,多加了一個空格,所以各位需要慎重和小心
This is ^ test.                      //在正則表達式中,空格作為字符計。
[root@service99 regular]# grep --color '0$' price.txt 
$5.00
[root@service99 regular]# grep --color '9$' price.txt 
This price is $4.99

聯合定位

比較常用的就是“^$” 表示空行
結合“^#”,由于#在Linux代表注釋
輸出該文本的有效配置

[root@service99 regular]# cat -n /etc/vsftpd/vsftpd.conf | wc -l
121
[root@service99 regular]# grep -vE '^#|^$' /etc/vsftpd/vsftpd.conf   //v表示反選,E表示支持擴展正則“|”是擴展正則的符號,往下看,后面有
anonymous_enable=YES
local_enable=YES
write_enable=YES
local_umask=022
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES
anon_umask=022
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_std_format=YES
listen=YES
pam_service_name=vsftpd
userlist_enable=YES
tcp_wrappers=YES

字符出現范圍

{n,m} //前一個字符出現了n到m次
{n,} //前一個字符出現了n次以上
{n} //前一個字符出現了n次

[root@service99 regular]# grep --color "12345\{0,1\}" price.txt 
1234556
[root@service99 regular]# grep --color "12345\{0,2\}" price.txt 
1234556

點字符

點特殊字符用于匹配除換行符之外的任意單個字符,但點字符必須匹配一個字符;如果在圓點位置沒有字符,那么模式匹配失敗。

[root@service99 regular]# grep --color ".s" price.txt 
This price is $4.99
This is "\".
This is ^ test. 
[root@service99 regular]# grep --color ".or" price.txt 
hello,world!

字符類

字符類可以定義一類字符來匹配文本模式中的某一位置。如果在字符類中的某一字符在數據流中,就和模式匹配。
為定義字符類,需要使用方括號。應該將要包括在該類中的所有字符用方括號括起來,然后模式中使用整個字符類,就像任意的其他通配符一樣。

[root@service99 regular]# grep --color "[abcdsxyz]" price.txt 
This price is $4.99
hello,world!
This is "\".
This is ^ test. 
[root@service99 regular]# grep --color "[sxyz]" price.txt 
This price is $4.99
This is "\".
This is ^ test. 
[root@service99 regular]# grep --color "[abcd]" price.txt 
This price is $4.99
hello,world!
[root@service99 regular]# grep --color "Th[ais]" price.txt //Th 后的第一個字符在【ais】中匹配的
This price is $4.99
This is "\".
This is ^ test. 
[root@service99 regular]# grep -i  --color "th[ais]" price.txt  //-i 表示不區分大小寫
This price is $4.99
This is "\".
This is ^ test. 

如果不能確定某個字符的大小寫,就可以使用該模式:

[root@service99 regular]# echo "Yes" | grep --color "[yY]es"    []內字符順序沒有影響
Yes
[root@service99 regular]# echo "yes" | grep --color "[Yy]es"
yes

在單個表達式內可以使用多個字符類:

[root@service99 regular]# echo "Yes/no" | grep "[Yy][Ee]"
Yes/no
[root@service99 regular]# echo "Yes/no" | grep "[Yy].*[Nn]" //*在正則表達式中的用法,請往下看
Yes/no

字符類對數字同樣支持:

[root@service99 regular]# echo "My phone number is 123456987" | grep --color "is [1234]"
My phone number is 123456987
[root@service99 regular]# echo "This is Phone1" | grep --color "e[1234]"
This is Phone1
[root@service99 regular]# echo "This is Phone1" | grep --color "[1]"
This is Phone1

字符類還有一種極為常見的用途是解析可能拼錯的單詞:

[root@service99 regular]# echo "regular" | grep --color "r[ea]g[ua]l[ao]"
regular

否定字符類

用于查找不在該字符類中的字符,只需在字符類范圍的開頭添加脫字符(^).
即使使用否定,字符類仍必須匹配一個字符。

[root@service99 regular]# cat price.txt 
This price is $4.99
hello,world!
$5.00
#$#$
This is "\".
this is ^ test. 
cat
car
[root@service99 regular]# sed -n '/[^t]his/p' price.txt 
This price is $4.99
This is "\".
[root@service99 regular]# grep --color "[^t]his" price.txt 
This price is $4.99
This is "\".
[root@service99 regular]# grep --color "ca[tr]" price.txt 
cat
car
[root@service99 regular]# grep --color "ca[^r]" price.txt 
cat

使用范圍

當你需要匹配的字符很多并且有一定規律時,可以這樣:

[root@service99 regular]# cat price.txt 
This price is $4.99
hello,world!
$5.00
#$#$
This is "\".
this is ^ test. 
cat
car
1234556
911
11806
[root@service99 regular]# egrep --color '[a-z]' price.txt 
This price is $4.99
hello,world!
This is "\".
this is ^ test. 
cat
car
[root@service99 regular]# egrep --color '[A-Z]' price.txt 
This price is $4.99
This is "\".
[root@service99 regular]# grep --color "[0-9]" price.txt 
This price is $4.99
$5.00
1234556
911
11806

[root@service99 regular]# sed -n '/^[^a-Z]/p' price.txt 
$5.00
#$#$
1234556
911
11806
[root@service99 regular]# grep --color "^[^a-Z]" price.txt 
$5.00
#$#$
1234556
911
11806
[root@service99 regular]# echo $LANG    //在使用 [a-Z]時,注意LANG環境變量的值,該值若是進行修改的話,要注意修改的值的合法性
zh_CN.UTF-8 
[root@service99 regular]# LANG=en_US.UTF-8

特殊字符類

用于匹配特定類型的字符。
[[:blank:]] 空格(space)與定位(tab)字符
[[:cntrl:]] 控制字符
[[:graph:]] 非空格(nonspace)字符
[[:space:]] 所有空白字符
[[:print:]] 可顯示的字符
[[:xdigit:]] 十六進制數字
[[:punct:]] 所有標點符號
[[:lower:]] 小寫字母
[[:upper:]] 大寫字母
[[:alpha:]] 大小寫字母
[[:digit:]] 數字
[[:alnum:]] 數字和大小寫字母

星號

在某個字符之后加一個星號表示該字符在匹配模式的文本中不出現或出現多次

[root@service99 regular]# cat test.info 
goole
go go go
come on
goooooooooo
[root@service99 regular]# grep --color "o*" test.info 
goole
go go go
come on
goooooooooo
[root@service99 regular]# grep --color "go*" test.info 
goole
go go go
goooooooooo
[root@service99 regular]# grep --color "w.*d" price.txt     //經常與.一起使用
hello,world!

擴展正則表達式

問號

問號表示前面的字符可以不出現或者出現一次。不匹配重復出現的字符。

[root@service99 regular]# egrep --color "91?" price.txt 
This price is $4.99
911

加號

加號表示前面的字符可以出現一次或者多次,但必須至少出現一次,該字符若是不存在,則模式不匹配。

[root@service99 regular]# egrep --color "9+" price.txt 
This price is $4.99
911
[root@service99 regular]# egrep --color "1+" price.txt 
1234556
911
11806

使用大括號

使用大括號指定對可重復的正則表達式的限制,通常稱為間隔。

  • m:該正則表達式正好出現m次
  • m,n:該正則表達式出現最少m次,最多n次
[root@service99 regular]# echo "This is test,test is file." | egrep --color "test{0,1}"
This is test,test is file.
[root@service99 regular]# echo "This is test,test is file." | egrep --color "is{1,2}"
This is test,test is file.

正則表達式實例

這里有一個實例,對基本的正則表達式進行了練習和實例。
因為正則表達式,單看概念或者理論還是比較簡單的,然而在實際的使用中,卻不是那么好用,一旦用好了,對效率的提升絕對時可觀的。

素材文件:
"Open Source" is a good mechanism to develop programs.
apple is my favorite food.
Football game is not use feet only.
this dress doesn't fit me.
However, this dress is about $ 3183 dollars.
GNU is free air not free beer.
Her hair is very beauty.
I can't finish the test.
Oh! The soup taste good.
motorcycle is cheap than car.
This window is clear.
the symbol '*' is represented as start.
Oh! My god!
The gd software is a library for drafting programs.
You are the best is mean you are the no. 1.
The world <Happy> is the same with "glad".
I like dog.
google is the best tools for search keyword.
goooooogle yes!

go! go! Let's go.
# I am VBird

1.過濾下載文件中包含 the 關鍵字
grep --color "the" regular_express.txt
2.過濾下載文件中丌包含 the 關鍵字
grep --color -vn "the" regular_express.txt
3.過濾下載文件中丌論大小寫 the 關鍵字
grep --color -in "the" regular_express.txt
4.過濾 test 或 taste 這兩個單字
grep --color -En 'test|taste' regular_express.txt
grep --color -i "t[ae]ste\{0,1\}" 1.txt
5.過濾有 oo 的字節
grep --color "oo" regular_express.txt
6.過濾丌想要 oo 前面有 g 的
grep --color [^g]"oo" regular_express.txt
grep --color "[^g]oo" regular_express.txt
7.過濾 oo 前面丌想有小寫字節
egrep --color "[^a-z]oo" regular_express.txt
8.過濾有數字的那一行
egrep --color [0-9] regular_express.txt
9.過濾以 the 開頭的
egrep --color ^the regular_express.txt
10.過濾以小寫字母開頭的
egrep --color ^[a-z] regular_express.txt
11.過濾開頭丌是英文字母
egrep --color ^[^a-Z] regular_express.txt
12.過濾行尾結束為小數點.那一行
egrep --color $"\." regular_express.txt
13.過濾空白行
egrep --color "^$" regular_express.txt
14.過濾出 g??d 的字串
egrep --color "g..d" regular_express.txt
15.過濾至少兩個 o 以上的字串
egrep --color "ooo*" regular_express.txt
egrep --color o\{2,\} regular_express.txt
16.過濾 g 開頭和 g 結尾但是兩個 g 之間僅存在至少一個 o
egrep --color go\{1,\}g regular_express.txt
17.過濾任意數字的行
egrep --color [0-9] regular_express.txt
18.過濾兩個 o 的字串
egrep --color "oo" regular_express.txt
19.過濾 g 后面接 2 到 5 個 o,然后在接一個 g 的字串
egrep --color go\{2,5\}g regular_express.txt
20.過濾 g 后面接 2 個以上 o 的
egrep --color go\{2,\} regular_express.txt

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,238評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,430評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,134評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,893評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,653評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,136評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,212評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,372評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,888評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,738評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,939評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,482評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,179評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,588評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,829評論 1 283
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,610評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,916評論 2 372

推薦閱讀更多精彩內容