實驗樓 正則表達式基礎

 

基本語法:

選擇

|豎直分隔符表示選擇,例如"boy|girl"能夠匹配"boy"或者"girl"css

數量限定

數量限定除了咱們舉例用的*,還有+加號,?問號,若是在一個模式中不加數量限定符則表示出現一次且僅出現一次:linux

  • +表示前面的字符必須出現至少一次(1次或屢次),例如,"goo+gle",能夠匹配"gooogle","goooogle"等;
  • ?表示前面的字符最多出現一次(0次或1次),例如,"colou?r",能夠匹配"color"或者"colour";
  • *星號表明前面的字符能夠不出現,也能夠出現一次或者屢次(0次、或1次、或屢次),例如,「0*42」能夠匹配4二、04二、004二、00042等。

範圍和優先級

()圓括號能夠用來定義模式字符串的範圍和優先級,這能夠簡單的理解爲是否將括號內的模式串做爲一個總體。例如,"gr(a|e)y"等價於"gray|grey",(這裏體現了優先級,豎直分隔符用於選擇a或者e而不是gra和ey),"(grand)?father"匹配father和grandfather(這裏體驗了範圍,?將圓括號內容做爲一個總體匹配)。git

字符 描述
\ 將下一個字符標記爲一個特殊字符、或一個原義字符。例如,「n」匹配字符「n」。「\n」匹配一個換行符。序列「\\」匹配「\」而「\(」則匹配「(」。
^ 匹配輸入字符串的開始位置。
$ 匹配輸入字符串的結束位置。
{n} n是一個非負整數。匹配肯定的n次。例如,「o{2}」不能匹配「Bob」中的「o」,可是能匹配「food」中的兩個o。
{n,} n是一個非負整數。至少匹配n次。例如,「o{2,}」不能匹配「Bob」中的「o」,但能匹配「foooood」中的全部o。「o{1,}」等價於「o+」。「o{0,}」則等價於「o*」。
{n,m} m和n均爲非負整數,其中n<=m。最少匹配n次且最多匹配m次。例如,「o{1,3}」將匹配「fooooood」中的前三個o。「o{0,1}」等價於「o?」。請注意在逗號和兩個數之間不能有空格。
* 匹配前面的子表達式零次或屢次。例如,zo*能匹配「z」、「zo」以及「zoo」。*等價於{0,}。
+ 匹配前面的子表達式一次或屢次。例如,「zo+」能匹配「zo」以及「zoo」,但不能匹配「z」。+等價於{1,}。
? 匹配前面的子表達式零次或一次。例如,「do(es)?」能夠匹配「do」或「does」中的「do」。?等價於{0,1}。
? 當該字符緊跟在任何一個其餘限制符(*,+,?,{n},{n,},{n,m})後面時,匹配模式是非貪婪的。非貪婪模式儘量少的匹配所搜索的字符串,而默認的貪婪模式則儘量多的匹配所搜索的字符串。例如,對於字符串「oooo」,「o+?」將匹配單個「o」,而「o+」將匹配全部「o」。
. 匹配除「\n」以外的任何單個字符。要匹配包括「\n」在內的任何字符,請使用像「(.|\n)」的模式。
(pattern) 匹配pattern並獲取這一匹配的子字符串。該子字符串用於向後引用。要匹配圓括號字符,請使用「\(」或「\)」。
x|y 匹配x或y。例如,「z|food」能匹配「z」或「food」。「(z|f)ood」則匹配「zood」或「food」。
[xyz] 字符集合(character class)。匹配所包含的任意一個字符。例如,「[abc]」能夠匹配「plain」中的「a」。其中特殊字符僅有反斜線\保持特殊含義,用於轉義字符。其它特殊字符如星號、加號、各類括號等均做爲普通字符。脫字符^若是出如今首位則表示負值字符集合;若是出如今字符串中間就僅做爲普通字符。連字符 - 若是出如今字符串中間表示字符範圍描述;若是若是出如今首位則僅做爲普通字符。
[^xyz] 排除型(negate)字符集合。匹配未列出的任意字符。例如,「[^abc]」能夠匹配「plain」中的「plin」。
[a-z] 字符範圍。匹配指定範圍內的任意字符。例如,「[a-z]」能夠匹配「a」到「z」範圍內的任意小寫字母字符。
[^a-z] 排除型的字符範圍。匹配任何不在指定範圍內的任意字符。例如,「[^a-z]」能夠匹配任何不在「a」到「z」範圍內的任意字符。

優先級爲從上到下從左到右,依次下降:正則表達式

運算符 說明
\ 轉義符
(), (?:), (?=), [] 括號和中括號
*、+、?、{n}、{n,}、{n,m} 限定符
^、$、\任何元字符 定位點和序列
 選擇

grep模式匹配命令

基本操做

grep命令用於打印輸出文本中匹配的模式串,它使用正則表達式做爲模式匹配的條件。編程

在經過grep命令使用正則表達式以前,先介紹一下它的經常使用參數:vim

參數 說明
-b 將二進制文件做爲文原本進行匹配
-c 統計以模式匹配的數目
-i 忽略大小寫
-n 顯示匹配文本所在行的行號
-v 反選,輸出不匹配行的內容
-r 遞歸匹配查找
-A n n爲正整數,表示after的意思,除了列出匹配行以外,還列出後面的n行
-B n n爲正整數,表示before的意思,除了列出匹配行以外,還列出前面的n行
--color=auto 將輸出中的匹配項設置爲自動顏色顯示

使用正則表達式

使用基本正則表達式,BRE

  • 位置

查找/etc/group文件中以"shiyanlou"爲開頭的行ruby

$ grep 'shiyanlou' /etc/group $ grep '^shiyanlou' /etc/group
  • 數量
# 將匹配以'z'開頭以'o'結尾的全部字符串 $ echo 'zero\nzo\nzoo' | grep 'z.*o' # 將匹配以'z'開頭以'o'結尾,中間包含一個任意字符的字符串 $ echo 'zero\nzo\nzoo' | grep 'z.o' # 將匹配以'z'開頭,以任意多個'o'結尾的字符串 $ echo 'zero\nzo\nzoo' | grep 'zo*' 

注意:其中\n爲換行符bash

  • 選擇
# grep默認是區分大小寫的,這裏將匹配全部的小寫字母 $ echo '1234\nabcd' | grep '[a-z]' # 將匹配全部的數字 $ echo '1234\nabcd' | grep '[0-9]' # 將匹配全部的數字 $ echo '1234\nabcd' | grep '[[:digit:]]' # 將匹配全部的小寫字母 $ echo '1234\nabcd' | grep '[[:lower:]]' # 將匹配全部的大寫字母 $ echo '1234\nabcd' | grep '[[:upper:]]' # 將匹配全部的字母和數字,包括0-9,a-z,A-Z $ echo '1234\nabcd' | grep '[[:alnum:]]' # 將匹配全部的字母 $ echo '1234\nabcd' | grep '[[:alpha:]]'
# 排除字符 $ $ echo 'geek\ngood' | grep '[^o]' 

注意:^放到中括號內爲排除字符,不然表示行首。markdown

下面包含完整的特殊符號及說明:app

 

特殊符號 說明
[:alnum:] 表明英文大小寫字節及數字,亦即 0-9, A-Z, a-z
[:alpha:] 表明任何英文大小寫字節,亦即 A-Z, a-z
[:blank:] 表明空白鍵與 [Tab] 按鍵二者
[:cntrl:] 表明鍵盤上面的控制按鍵,亦即包括 CR, LF, Tab, Del.. 等等
[:digit:] 表明數字而已,亦即 0-9
[:graph:] 除了空白字節 (空白鍵與 [Tab] 按鍵) 外的其餘全部按鍵
[:lower:] 表明小寫字節,亦即 a-z
[:print:] 表明任何能夠被列印出來的字節
[:punct:] 表明標點符號 (punctuation symbol),亦即:" ' ? ! ; : # $...
[:upper:] 表明大寫字節,亦即 A-Z
[:space:] 任何會產生空白的字節,包括空白鍵, [Tab], CR 等等
[:xdigit:] 表明 16 進位的數字類型,所以包括: 0-9, A-F, a-f 的數字與字節

 

使用擴展正則表達式,ERE

要經過grep使用擴展正則表達式須要加上-E參數,或使用egrep

  • 數量
# 只匹配"zo" $ echo 'zero\nzo\nzoo' | grep -E 'zo{1}' # 匹配以"zo"開頭的全部單詞 $ echo 'zero\nzo\nzoo' | grep -E 'zo{1,}' 
  • 選擇
# 匹配"www.shiyanlou.com"和"www.google.com" $ echo 'www.shiyanlou.com\nwww.baidu.com\nwww.google.com' | grep -E 'www\.(shiyanlou|google)\.com' # 或者匹配不包含"baidu"的內容 $ echo 'www.shiyanlou.com\nwww.baidu.com\nwww.google.com' | grep -Ev 'www\.baidu\.com' 

sed 流編輯器

sed工具在 man 手冊裏面的全名爲"sed - stream editor for filtering and transforming text",意即,用於過濾和轉換文本的流編輯器。

sed經常使用參數介紹

sed 命令基本格式:

sed [參數]... [執行命令] [輸入文件]...
# 形如: $ sed -i '1s/sad/happy/' test # 表示將test文件中第一行的"sad"替換爲"happy" 
參數 說明
-n 安靜模式,只打印受影響的行,默認打印輸入數據的所有內容
-e 用於在腳本中添加多個執行命令一次執行,在命令行中執行多個命令一般不須要加該參數
-f filename 指定執行filename文件中的命令
-r 使用擴展正則表達式,默認爲標準正則表達式
-i 將直接修改輸入文件內容,而不是打印到標準輸出設備

sed編輯器的執行命令(這裏」執行「解釋爲名詞)

[n1][,n2]command [n1][~step]command # 其中一些命令能夠在後面加上做用範圍,形如: $ sed -i 's/sad/happy/g' test # g表示全局範圍 $ sed -i 's/sad/happy/4' test # 4表示指定行中的第四個匹配字符串

sed執行命令格式:

[n1][,n2]command [n1][~step]command # 其中一些命令能夠在後面加上做用範圍,形如: $ sed -i 's/sad/happy/g' test # g表示全局範圍 $ sed -i 's/sad/happy/4' test # 4表示指定行中的第四個匹配字符串 

其中n1,n2表示輸入內容的行號,它們之間爲,逗號則表示從n1到n2行,若是爲波浪號則表示從n1開始以step爲步進的全部行;command爲執行動做,下面爲一些經常使用動做指令:

命令 說明
s 行內替換
c 整行替換
a 插入到指定行的後面
i 插入到指定行的前面
p 打印指定行,一般與-n參數配合使用
d 刪除指定行

 

sed操做舉例

咱們先找一個用於練習的文本文件:

$ cp /etc/passwd ~

打印指定行

# 打印2-5行 $ nl passwd | sed -n '2,5p' # 打印奇數行 $ nl passwd | sed -n '1~2p' 

 

行內替換

# 將輸入文本中"shiyanlou" 全局替換爲"hehe",並只打印替換的那一行,注意這裏不能省略最後的"p"命令 $ sed -n 's/shiyanlou/hehe/gp' passwd 

注意: 行內替換能夠結合正則表達式使用。

 

行間替換

$ nl passwd | grep "shiyanlou" # 刪除第21行 $ sed -n '21c\www.shiyanlou.com' passwd (這裏咱們只把要刪的行打印出來了,並無真正的刪除,若是要刪除的話,請使用-i參數) 

awk文本處理語言

AWK是一種用於處理文本的編程語言工具。

awk的一些基礎概念

awk全部的操做都是基於pattern(模式)—action(動做)對來完成的,以下面的形式:


你能夠看到就如同不少編程語言同樣,它將全部的動做操做用一對花括號包圍起來。其中pattern一般是是表示用於匹配輸入的文本的「關係式」或「正則表達式」,action則是表示匹配後將執行的動做。在一個完整awk操做中,這二者能夠只有其中一個,若是沒有pattern則默認匹配輸入的所有文本,若是沒有action則默認爲打印匹配內容到屏幕。$ pattern {action}{}

 

awk命令基本格式

awk [-F fs] [-v var=value] [-f prog-file | 'program text'] [file...] 

其中-F參數用於預先指定前面提到的字段分隔符(還有其餘指定字段的方式) ,-v用於預先爲awk程序指定變量,-f參數用於指定awk命令要執行的程序文件,或者在不加-f參數的狀況下直接將程序語句放在這裏,最後爲awk須要處理的文本輸入,且能夠同時輸入多個文本文件。

awk操做體驗

先用vim新建一個文本文檔

$ vim test 

包含以下內容:

I like linux www.shiyanlou.com 
  • 使用awk將文本內容打印到終端
# "quote>" 不用輸入 $ awk '{ > print > }' test # 或者寫到一行 $ awk '{print}' test 

說明:在這個操做中我是省略了pattern,因此awk會默認匹配輸入文本的所有內容,而後在"{}"花括號中執行動做,即print打印全部匹配項,這裏是所有文本內容

  • 將test的第一行的每一個字段單獨顯示爲一行
$ awk '{ > if(NR==1){ > print $1 "\n" $2 "\n" $3 > } else { > print} > }' test # 或者 $ awk '{ > if(NR==1){ > OFS="\n" > print $1, $2, $3 > } else { > print} > }' test 

說明:你首先應該注意的是,這裏我使用了awk語言的分支選擇語句if,它的使用和不少高級語言如C/C++語言基本一致,若是你有這些語言的基礎,這裏將很好理解。另外一個你須要注意的是NROFS,這兩個是awk內建的變量,NR表示當前讀入的記錄數,你能夠簡單的理解爲當前處理的行數,OFS表示輸出時的字段分隔符,默認爲" "空格,如上圖所見,咱們將字段分隔符設置爲\n換行符,因此第一行本來以空格爲字段分隔的內容就分別輸出到單獨一行了。而後是$N其中N爲相應的字段號,這也是awk的內建變量,它表示引用相應的字段,由於咱們這裏第一行只有三個字段,因此只引用到了$3。除此以外另外一個這裏沒有出現的$0,它表示引用當前記錄(當前行)的所有內容。

  • 將test的第二行的以點爲分段的字段換成以空格爲分
$ awk -F'.' '{ > if(NR==2){ > print $1 "\t" $2 "\t" $3 > }}' test # 或者 $ awk ' > BEGIN{ > FS="." > OFS="\t" # 若是寫爲一行,兩個動做語句之間應該以";"號分開 > }{ > if(NR==2){ > print $1, $2, $3 > }}' test
說明:這裏的-F參數,前面已經介紹過,它是用來預先指定待處理記錄的字段分隔符。咱們須要注意的是除了指定OFS咱們還能夠在print 語句中直接打印特殊符號如這裏的\tprint打印的非變量內容都須要用""一對引號包圍起來。上面另外一個版本,展現了實現預先指定變量分隔符的另外一種方式,即便用BEGIN,就這個表達式指示了,其後的動做將在全部動做以前執行,這裏是FS賦值了新的"."點號代替默認的" "空格
-FOFSprint\tBEGINFS

awk經常使用的內置變量

變量名 說明
FILENAME 當前輸入文件名,如有多個文件,則只表示第一個。若是輸入是來自標準輸入,則爲空字符串
$0 當前記錄的內容
$N N表示字段號,最大值爲NF變量的值
FS 字段分隔符,由正則表達式表示,默認爲" "空格
RS 輸入記錄分隔符,默認爲"\n",即一行爲一個記錄
NF 當前記錄字段數
NR 已經讀入的記錄數
FNR 當前輸入文件的記錄數,請注意它與NR的區別
OFS 輸出字段分隔符,默認爲" "空格
ORS 輸出記錄分隔符,默認爲"\n"
相關文章
相關標籤/搜索