正則表達式練習筆記

下面的內容是一個 data1.txt 文本內容,裏面記錄了一些正則表達式的筆記

long long ago there is girl, she's name is little redhat..
long_long_long#long;long:long
This is a test txt...
my phone number is 18621735531


There are a lot of good books,

220123
12345

E-mail:[email protected]
new...............231592315y12#$@%#$@^%$^$@<>?{}|}S#$!@#%


ik
iek
ieek
ieeek
ieeeek
ieeeeek
ieeeeeek

iek22222
iekddddd
iekwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
iek shit up

this is iekkkk string

nekkkk
cek
dek
sekjjjd


# 組合描點 grep -n ^$ data1.txt, 可以濾出來空白行
#grep -n This is ^a data1.txt
#grep -n ^[0-9][0-9][0-9][0-9][0-9]$ data1.txt \
#grep -n ie*k data1.txt 

一、錨點
鎖定行首 ^
鎖定行尾 $
組合錨點 ^$


二、單個字符匹配
字符組 [..]
[^...]
.  一個字符佔位符,不包括換行
*  匹配前一個字符出現任意次次數

=====================================我是分割線==================================
下面是擴展的 正則表達式

?  匹配前一個字符有或者沒有,就是0次要麼1次
+  匹配前一個字符需要出現的,不管次數

模式匹配次數
{m}  精確的m次數
{m,} 大於m次,n爲無窮大
{m,n} 大於m次, 小於n次

圓括號聚合匹配格式
()
(||)


舉個列子:比如下面的命令匹配 iek 字符串
#grep -n -E  ie\{1\}k data1.txt
#grep -n -E  ie{1}k data1.txt


匹配 ie 出現一次的,不是2次,也不是 se,de,其他字符串
#grep -n -E  ie\{1\} data1.txt

比如,給出下面一些字符串,想要匹配星期六的符串, Sat. 縮寫或者全寫 Saturday:

SatSomething
Satelse
Sat.
Saturday

# grep -n -E '^Sat(urday|.)?$' data1.txt




複雜的例子 一:匹配電話號碼,如下面四種形式
(223)456-7890
(223) 456-7890
223 456-7890
223     456-7890
223456-7890
223-456-7890
###223-456-7890
223.456.7890
223.456-7890
223-456.7890


分析,首先,開頭的 左邊圓括號 '\(' 可有可無的, 所以得到:

^\(?  

再看 123 是三個數字的區號,美國電話號碼區號是以2開始的數字開始的,最大到9, 後兩個數字任意的,因此匹配區號是:

[2-9][0-9]{2}

接下來分析區號後面, 收尾的右圓括號 '\)' 可能存在,也可能不存在,單獨去取出來和左邊對應,匹配方式爲:

\)?


接下來,可能有一個空格或者沒有, 一個破折號 '-' 一個點號 '\.' ,可以用管道符號可圓括號處理得到:

(| |-|\.)


接下來是三位電話交換機號碼,沒有什麼特殊的

[0-9]{3}

接下來,交換機號碼後面可能有一個空格,一個破折號或者一個點號

( |-|\.)

最後是尾部的四位本地電話分機號碼:

[0-9]{4}$

最後,拼接起來整個模式爲:

^\(?[2-9][0-9]{2}\)?(| |-|\.)[0-9]{3}( |-|\.)[0-9]{4}$

最後查找匹配合格的電話號碼:

nfs@nfs-Lenovo:~$ grep -n -E '^\(?[2-9][0-9]{2}\)?(| |-|\.)[0-9]{3}( |-|\.)[0-9]{4}$' data1.txt
91:(223)456-7890
92:(223) 456-7890
93:223 456-7890
95:223456-7890
96:223-456-7890
98:223.456.7890
99:223.456-7890
100:223-456.7890



思考,這個regex還有個bug, 就是 223456-7890也是合法寫法電話,想要把這個case排除,新的匹配模式怎麼寫?
如果 區號 沒有被括號包圍,那麼一定需要一個 空格隔開。。。。。。。。。。。。。。

答題:
需要將 區號 部分重新提煉出來處理,分成有括號的區號和沒有括號的區號,有括號區號匹配如下:

^\([2-9][0-9]{2}\)

沒有括號的區號匹配如下:

^[2-9][0-9]{2}


再次做一個改變,將區號後面的符號提到前面處理,因次分別得到:

^\([2-9][0-9]{2}\)(| |-|\.)

和(這個模式後面不跟空格,只有破折號和點號)

^[2-9][0-9]{2}( |-|\.)


將這兩種case合併得到下面的模式可以匹配區號:

(^\([2-9][0-9]{2}\)(| |-|\.)|^[2-9][0-9]{2}( |-|\.))

最後合併得到新的電話號碼匹配模式:


(^\([2-9][0-9]{2}\)(| |-|\.)|^[2-9][0-9]{2}( |-|\.))[0-9]{3}( |-|\.)[0-9]{4}$

進行測試:

$ grep -n -E '(^\([2-9][0-9]{2}\)(| |-|\.)|^[2-9][0-9]{2}( |-|\.))[0-9]{3}( |-|\.)[0-9]{4}$' data1.txt
91:(223)456-7890
92:(223) 456-7890
93:223 456-7890
96:223-456-7890
98:223.456.7890
99:223.456-7890
100:223-456.7890









複雜列子二:匹配郵箱地址

E-mail格式爲:

username@hostname

username可以使用的字符有 字母數字字符以及一些特殊字符,如下:

1.點號
2.破折號
3.加號
4.下劃線

所以,username匹配方式爲:

^([a-zA-Z0-9_\-\.\+]+)@

接下來分析 hostname的服務器名字和子域名,這部分可以是字母數字字符,以及點號和下劃線:

([a-zA-Z0-9_\-\.]+)

這個模式可以匹配文本:
server
server.subdomain
server.subdomain.subdomain


接下來就是 hostname中的頂級域名部分,不考慮中文域名,頂級域名要是是2到5個字母組成的,頂級域名爲:

\.([a-zA-Z]{2,5})$

所以匹配郵箱地址爲:

^([a-zA-Z0-9_\-\.\+]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$

[email protected]
[email protected]
[email protected]

$ grep -n -E '^([a-zA-Z0-9_\-\.\+]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$' data1.txt




最後一個列子,匹配QQ號碼,QQ號碼是6個以上的數字,假設最大數字是13,不以0開頭的,匹配模式如下:

^[1-9][0-9]{5,}$

測試如下QQ號碼:

038216437
123
12345
382164370
281120661
754198142
###754198142
754198142##
1123564020
11111111111111111111111111111465

nfs@nfs-Lenovo:~$ grep -n -E '^[1-9][0-9]{5,12}$' data1.txt
9:220123
253:382164370
254:754198142
255:1123564020


nfs@nfs-Lenovo:~$ grep -n -E '^[1-9][0-9]{5,12}$' data1.txt
9:220123
253:382164370
254:754198142
255:1123564020
nfs@nfs-Lenovo:~$ 

匹配整數寫法,整數前面一個破折號表示負數,或者一個可有可無的 + 號,匹配模式如下:


^(|-|\+)

接下來是第一個數字,非0,後面不限,因此

[1-9][0-9]*$

合併得到正數的匹配寫法是:

^(|-|\+)[1-9][0-9]*$

測試整數:
-1203
5554
+7894
-2222222
#24545

# grep -n -E '^(|-|\+)[1-9][0-9]*$' data1.txt



再寫一個簡單的,匹配字母數字字符串。

^[a-zA-Z0-9]+$

# grep -n -E '^[a-zA-Z0-9]+$' data1.txt


匹配空行

#grep -n -E '^$' data1.txt



最後一個奇怪的測試:

([\\/$]* | ?:[\\/]*)

測試:

x:\test\test
z:/test1/test1
${datarootdir}/doc/${PACKAGE_TARNAME}
${datarootdir}/doc/man


# grep -E '([\\/$]* | ?:[\\/]*)' data1.txt

















發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章