3-6:常见任务和主要工具之正则表达式
文章目錄
- 一:什么是正則表達式
- 二:grep-文本搜索
- 三:元字符和文字
- (1)任意字符——.
- (2)錨——^和$
- (3)中括號和字符類
- A:否定
- B:傳統字符范圍
- C:POSIX字符類
- (4)或和組合
- (5)限定符
- A:匹配元素0次或者是1次-?
- B:匹配任意字符多次或零次-*
- C:匹配某元素一次或多次-+
- D:以指定次數匹配某元素
一:什么是正則表達式
正則表達式(Regular Expression)是一種文本模式,包括普通字符(例如,a 到 z 之間的字母)和特殊字符(稱為"元字符")。
正則表達式使用單個字符串來描述、匹配一系列匹配某個句法規則的字符串。正則表達式是繁瑣的,但它是強大的,學會之后的應用會讓你除了提高效率外,會給你帶來絕對的成就感。只要認真閱讀本教程,加上應用的時候進行一定的參考,掌握正則表達式不是問題。許多程序設計語言都支持利用正則表達式進行字符串操作。
二:grep-文本搜索
正如Python中的正則表達式工具可以用到re.match一樣,在Linux中用來處理正則表達式的主要程序是grep。實際上,grep搜索文本文件中與指定正則表達式匹配的行,并將結果輸出到標準輸出。
grep程序按照如下方式接受選項和參數
grep [options] regex [file],其中regex代表某個正則表達式
下標列出了grep的常用選項
比如對如下文件,使用grep搜索
三:元字符和文字
大家可能會感覺到很奇怪,但是grep的確是在使用正則表達式。比如上圖中的grep baby test.txt,就是在匹配文本中至少包含4個字符,存在連續的,按照b,a,b,y順序組成的字符串的行 其中的bzip都是文本字符,也就是他們只能匹配自己,b只能匹配b,除了文字字符,更多的正則表達式使用元字符完成更復雜的匹配操作。
有:^ $ . [ ] { } - ? * + ( ) | \
可以發現,上面很多元字符在shell中具有特殊含義,所以在執行時有時要用引號避免引起擴展
(1)任意字符——.
.這個元字符用于匹配任意字符
比如grep ".zip" test.txt,表示匹配zip,并且z前面以任意字符開頭
-
注意zip這個字符并沒有匹配,因為.zip匹配的是4個字符
-
而且如果某個字符中直接包含了.zip,那么也是可以匹配到的,因為.也會被當做任意字符處理
(2)錨——^和$
^表示開頭,$表示末尾
比如要查找以z開頭,包含zip的行
比如只是要匹配zip
(3)中括號和字符類
簡單點說中括號內的字符只要滿足,就可以匹配得到
比如說要匹配bzip或gzip就可以這樣操作
一個字符集可以包含任意數目的字符,并且元字符放到中括號時,就會時期他們的特殊含義。
有兩種情況,中括號使用元字符時會有不同的含義:^在中括號使用時表示否定,-則表示字符范圍
A:否定
當中括號的第一個字符是^時,那么剩下的字符就表示“不應該有”
修改上圖中的例子,就表示匹配那些包含zip字符但是zip前面既不是b也不是g
- 注意如果不把^放在中括號的第一個位置,那么其否定意義就喪失了,就成為了普通字符
B:傳統字符范圍
如果希望匹配所有以大寫字母開頭的文件,你可以這樣輸入
這樣輸入有沒有錯誤?當然沒有,但是很明顯太麻煩了,所以我們可以使用-,也就是連字符
如果將連字符放到中括號的第一個位置,那么連字符就是轉化為了普通字符。
C:POSIX字符類
講這個主題前,先說一個問題。如下使用兩種方式匹配以任意大寫字母開頭的命令,為什么結果不一樣,并且相差這么大?
關于出現這個問題的原因,書中也做了詳細的介紹
所以為了解決這樣的問題,POSIX標準包含了許多標準字符類,這些字符類提供了一些很有用的字符范圍
于是這里我們可以使用他們來進行匹配
POSIX規范將正則表達式分為了基本正則表達式(BRE)和擴展正則表達式(ERE)兩類,到目前為止,我們所討論的正則表達式的所有特性,都得到了兼容POSIX的應用程序的支持,并且都是以BRE的方式實現的(比如說grep)
在BRE中,只承認^ $ . [ ] *是元字符,其他字符一律被視為文字字符,而在ERE中,添加了( ) { } ? + |等元字符
所以以下討論的選項中,grep要加上-e選項,依次支持這些元字符
(4)或和組合
| 表示或,用于從字符串集或正則表達式集中尋找匹配項
如下命令含義是匹配字符串AAA或字符串BBB
()的意思是組合,比如說grep -E "^bz|gz|zip" file.txt,表示匹配以bz或者是包含gz和zip的行,而grep -E" ^(bz|gz|zip)" file.txt則表示匹配以bz開頭或gz開頭或zip開頭的行
(5)限定符
A:匹配元素0次或者是1次-?
?的意思是前面的字符可以不出現,但是出現的話只能出現一次。
舉個例子,我們知道我們國家手機號可以寫作+8613930681613,也可以寫作13930681613,這意味著前面國家地區號可以不出現,所以出現可以書寫正則表達式如下grep -E "(\+[0-9][0-9])?[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]" test.txt,其中“+”是元字符,所以要進行轉義,?之前表示括號內的可以不出現,但是出現只能出現1次
如下,兩種手機號都被匹配到了
B:匹配任意字符多次或零次-*
*是我們最常使用的一個元字符,它表示匹配任意字符多次。比如我們經常在命令行使用rm -f *.txt表示刪除任意字符開頭,任意長度但是以.txt結尾的文件
舉個例子,我們都知道QQ郵箱都是以QQ號,也就是數字開頭并以@qq.com結尾,那么匹配一個QQ郵箱的正則表達式就是grep -E "^[0-9]*@qq.com" test2.txt
C:匹配某元素一次或多次-+
+和?的區別就是+匹配時起碼得出現1次。grep -E "(\+[0-9][0-9])?[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]" test.txt將其改為grep -E "(\+[0-9][0-9])+[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]" test.txt,這將導致沒有國際區號的那個手機號無法匹配到
D:以指定次數匹配某元素
{ }元字符用于描述最小和最大次數的需求匹配
有如下4種方法指定
這樣的話前面匹配手機號的那個就可以簡寫為 grep -E "(\+[0-9]{2})?[0-9]{11}" test.txt,分別表示前面的字符可以出現2次和11次
總結
以上是生活随笔為你收集整理的3-6:常见任务和主要工具之正则表达式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于Windows消息钩子的理解与测试项
- 下一篇: #include NOIP2009 Ju