正則表達式是個什么東東?
正則表達式,又稱正規表示法、常規表示法(英語:Regular Expression,在代碼中常簡寫為regex、regexp或RE)。在很多文本編輯器里、命令中,通常要使用檢索、替換、放行和拒絕那些符合某個模式的文本。而正則表達式就是用于描述這些規則的工具。換句話說,正則表達式就是記錄文本規則的代碼。
摘自《正則表達式之道》)
正則表達式 由一些普通字符和一些元字符(metacharacters)組成。普通字符包括大小寫的字母和數字,而元字符則具有特殊的含義,我們下面會給予解釋。
在最簡單的情況下,一個正則表達式看上去就是一個普通的查找串。例如,正則表達式"testing"中沒有包含任何元字符,它可以匹配"testing"和"testing123"等字符串,但是不能匹配"Testing"。
要想真正的用好正則表達式,正確的理解元字符是最重要的事情。下表列出了所有的元字符和對它們的一個簡短的描述。元字符是工具,組合起來就是方式,普通字符是目標。目標有一個方式有多種。
正則表達式分類標準正則表達式和擴展正則表達式;主要的區別是在于一些元字符的書寫方式和支持上,沒有根本的區別。
靈活運用這些元字符來對字符進行匹配示例
匹配合理的的IPV4地址
1.0.0.1-239.255.255.255
1、IPV4地址是以四組點分十進制來表示的,固定的字符 . 這個 . (點)是固定的有三個把這串字符分為了四組;. (點)在正則表達式內是元字符,那么對它進行匹配需要進行轉義;也就是”\.”在正則表達式內才表示為點。
如圖所示這樣就能匹配出 “.”來了
2、四組的取值范圍分別是 “1-239”.”0-255”.”0-255”.”1-255”
我們先看第一組 “1-239”. 就是在1……….…239中的字符出現一次其實就是1或2或3或…..239;正則表達式寫成1|2|3…..|239肯定可以就是太累了,估計這么寫會被直接咔嚓的。哎!1|2|3|4|5|6|7|8|9|10..|99|100…|199|200..|239按照個位十位百位來
1|2|3|4|5|6|7|8|9 不就是[1-9];
|10..|99 不就是[1-9][0-9];
100…|199| 不就是[1][0-9][0-9];
200..|239 不就是[2][0-3][0-9]
組合起來[1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-3][0-9]
驗證一下:首先我們看下 ifconfig 顯示的內容中都有哪些數字
用我們寫好的去匹配下看看是不是1-239的
對比下確實0和比239大的數字都沒有出現,也就是說這個表達式正常的匹配到我們需要匹配的字符集。
剩下的我們依葫蘆畫瓢
[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5] 0-255
[1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5] 1-255
好吧我們把它組合起來
[1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-3][0-9][\.][0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5] [\.][0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5][\.][1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]
對不對先放一邊真長啊,一準看花眼。先試試對不對。
哇不對,怎么顯示的都是一個一個的單個數啊,對了這是被.(點)給分開的四組字符串,應該分組。 分組再試!
噢耶大功告成。
不過我總覺得有點長,看著太累。
([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-3][0-9])[\.]([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])[\.]([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])[\.]([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])
試著去對表達式進行優化,
1、首先是已經對這個表達式進行了分組是否可以使用引用。
([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-3][0-9])[\.]([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])[\.]\2 [\.]([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])
出錯一開始我以為是我的\n的用法不對于是就把命令剪短后再次匹配
發現是可以陪陪的,但是發現沒有前后的字符是一樣的?回過頭來看一遍
\ | 引用第n個括號所匹配到的內容,而非模式本身 |
2、仔細查看表達式發現,里面有[1-9]|[1-9][0-9] 這是01-99 前面這個0-9可以不出現就是0-9了 太可惡了這么簡單明了的解釋都能出錯,哎我這智商完蛋了。
? | 匹配前面的子表達式零次或一次。(基本表達式需要轉意 \) |
[1-9]?[0-9] 應該就是表示對的1-99
[0-9]?[0-9] 應該表示的就是0-99
[0-9]出現0次或者1次后面跟上[0-9]出現一次,不就是[0-9]{1,2} 應也是表示的是0-99
去試試
ifconfig | grep -Eo "([1-9]?[0-9]|1[0-9][0-9]|2[0-3][0-9])[\.]([0-9]{1,2}|1[0-9][0-9]|2[0-4][0-9]|25[0-5])[\.]([0-9]{1,2}|1[0-9][0-9]|2[0-4][0-9]|25[0-5])[\.]( [1-9]?[0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])"
ifconfig | grep -Eo "([1-9]?[0-9]|1[0-9]{1,2}|2[0-3][0-9])[\.]([0-9]{1,2}|1[0-9]{1,2}|2[0-4][0-9]|25[0-5])[\.]([0-9]{1,2}|1[0-9]{1,2}|2[0-4][0-9]|25[0-5])[\.]([0-9]{1,2}|1[0-9]{1,2}|2[0-4][0-9]|25[0-5])"
所用的命令及參數
grep [option]... 'PATTERN' FILE... --color=auto 自動加點顏色顯示 -o: 僅顯示匹配的字串,而非字串所在的行 -E: 支持使用擴展正則表達式 -F: 不使用正則表達式
sort: 對文件內容進行排序 sort [option] FILE... -f: 忽略字符大小寫 -t: 指定分隔符 -k: 指定分隔之后要進行排序比較的字段 -n: 以數值大小進行排序 -u: 排序后去重
寫的不好還請指導O(∩_∩)O~
后面的啰嗦一點通配符
通配符:也是一種查找的工具能夠進行模糊查找,同時我所了解的就是還有一個網絡通配符。
*: 任意長度的任意字符
?: 匹配任意單字符
[ ]: 匹配指定范圍內的任意單字符 [abc], [a-z], [0-9], [0-9a-z]
[^]:匹配指定范圍以外的任意單字符 [^0-9a-z]
字符集合:使用需要加[ ]
[:space:] : 所有空白字符
[:punct:] : 所有標點符號
[:lower:] :所有小寫字母 [a-z] 不能寫成[z-a]
[:upper:] :所有大寫字母 [A-Z]
[:digit:] :所有數字 [0-9]
[:alnum:] :所有數字和字母 [A-Z0-9a-z]
[:alpha:] :所有字母 [a-zA-Z]
舉個例子: ls [*]*a.txt 查找以*開頭中間有任意字符以a.txt結尾的文件
[root@zhuzw-centos6 tmp]# ls
a *a**a.txt aa.txt a.txt ceshi.txt cpvar.sh keyring-bBocvt logs orbit-gdm pulse-jFNHHBiALmGU pulse-kCc9R2jshzlv zhuzw
[root@zhuzw-centos6 tmp]# ls [*]*a.txt
*a**a.txt
[root@zhuzw-centos6 tmp]# ls [^*]*a.txt
aa.txt
[root@zhuzw-centos6 tmp]# ls *[[:space:]]* 匹配空白字符
a a.txt
[root@zhuzw-centos6 tmp]# ls [a-zA-Z0-9]
ls: 無法訪問[a-zA-Z0-9]: 沒有那個文件或目錄
[root@zhuzw-centos6 tmp]# ls [a-zA-Z0-9].TXT
ls: 無法訪問[a-zA-Z0-9].TXT: 沒有那個文件或目錄
[root@zhuzw-centos6 tmp]# ls [a-zA-Z0-9].txt
a.txt
[root@zhuzw-centos6 tmp]# touch 0
[root@zhuzw-centos6 tmp]# ls [9-0]
ls: 無法訪問[9-0]: 沒有那個文件或目錄
[root@zhuzw-centos6 tmp]# ls [0-9]
0
通配符的這一個表達式表示一整串字符串,從左開始向右結束。主要用于模糊查找。當然了這并不全是通配符的全部功能之前在網絡中曾經用過一個網絡通配符就是0表示精準匹配,1表示不匹配。
通配符的還有適用于訪問控制列表(Access Control List,ACL)
R1#network 192.168.1.0 0.0.0.255
后面跟的這個和網絡掩碼是是反的,他表示就是192.168.1.x必須精準匹配,x可以為任意數,意思為宣告192.168.1.0/24 加入ospf區域
192.168.1.0 0.0.0.254匹配出192.168.1.0/24網段中的所有偶數地址
192.168.1.1 0.0.0.254匹配出192.168.1.0/24網段中的所有奇數地址
原創文章,作者:東郭先生,如若轉載,請注明出處:http://www.www58058.com/1810
內容詳實,有總結,有實踐, 但文章格式太亂,邏輯層次感稍弱,讀者初看有些無從下手, 后面的文章可以從這幾個方面著手優化。
寫得很好,但是疏忽了一個地方: ifconfig | grep -Eo “([1-9]?[0-9]|1[0-9]{1,2}|2[0-3][0-9])[\.]([0-9]{1,2}|1[0-9]{1,2}|2[0-4][0-9]|25[0-5])[\.]([0-9]{1,2}|1[0-9]{1,2}|2[0-4][0-9]|25[0-5])[\.]([0-9]{1,2}|1[0-9]{1,2}|2[0-4][0-9]|25[0-5])” 應該是“\”首位要錨定,不然會匹配到255.0.0.0 中的55.0.0.0
不好意思,應該是這樣 ifconfig | grep -Eo“\”
\《 和 \》,英文字符提交出錯;首尾要錨定 。
應該是這樣 ifconfig | grep -Eo “\b([1-9]?[0-9]|1[0-9]{1,2}|2[0-3][0-9])[\.]([0-9]{1,2}|1[0-9]{1,2}|2[0-4][0-9]|25[0-5])[\.]([0-9]{1,2}|1[0-9]{1,2}|2[0-4][0-9]|25[0-5])[\.]([0-9]{1,2}|1[0-9]{1,2}|2[0-4][0-9]|25[0-5])\b” 感謝麥鯨同學啊 :grin:
\b 和 \ 的效果是一樣的。