本文章參考 《Linux C 編程一站式學習》
引言
用 grep 可以在一個文件中找出包含某些字符串的行,比如在頭文件中找出一個宏定義。
其實 grep 還可以找出符合某個模式(Pattern)的一類字符串。例如找出所有符合 [email protected]模式的字符串(也就是email地址),要求 x 字符可以是字母、數字、下劃線、小數點或減號,email地址的每一部分可以有一個或多個x字符,例如[email protected]、[email protected],當然符合這個模式的不全是合法的email地址,但至少可以做一次初步篩選,篩掉 a.b、c@d 等肯定不是email地址的字符串。再比如,找出所有符合 yyy.yyy.yyy.yyy 模式的字符串(也就是IP地址),要求y是0-9的數字,IP地址的每一部分可以有1-3個y字符。
如果要用grep查找一個模式,如何表示這個模式,這一類字符串,而不是一個特定的字符串呢?從
這兩個簡單的例子可以看出,要表示一個模式至少應該包含以下信息:
字符類(Character Class): 如上例的 x 和 y,它們在模式中表示一個字符,但是取值範圍是一類字符中的任意一個。
數量限定符(Quantifier): 郵件地址的每一部分可以有一個或多個 x 字符,IP 地址的每一部分可以有1-3個 y 字符
位置關係: 例如郵件地址分三部分,用普通字符 @ 和 . 隔開,IP地址分四部分,用 . 隔開,每一部分都可以用字符類和數量限定符描述。下文介紹 位置限定符(Anchor) 的概念
正則表達式(Regular Expression)
規定一些特殊語法表示字符類、數量限定符和位置關係,然後用這些特殊語法和普通字符一起表示
一個模式,這就是正則表達式(Regular Expression)
例如email地址的正則表達式可以寫成 ^[a-zA-Z0-9_.-]+@[a-zA-Z0-9_.-]+.[a-zA-Z0-9_.-]+,IP地址的正則表達式可以寫成 ^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}
基本語法
字符類
字符 | 含義 | 舉例 |
---|---|---|
. | 匹配任意一個字符 | abc.可以匹配abcd、abc9等 |
[ ] | 匹配括號中的任意一個字符 | [abc]d可以匹配ad、bd或cd |
- | 在[]括號內表示字符範圍 | [0-9a-fA-F]可以匹配一位十六進制數字 |
^ | 位於[]括號內的開頭,匹配除括號中的字符之外的任意一個字符 | [^ xy]匹配除xy之外的任一符因此[^xy]1可以匹配a1、b1但不匹配x1、y1 |
數量限定符
字符 | 含義 | 舉例 |
---|---|---|
? | 緊跟在它前面的單元應匹配零次或一次 | [0-9]?.[0-9]匹配0.0、2.3、.5等,由於.在正則表達式中是一個特殊字符,所以需要用\轉義一下,取字面值 |
+ | 緊跟在它前面的單元應匹配一次或多次 | [a-zA-Z0-9_.-]+@[a-zA-Z0-9_.-]+.[a-zA-Z0-9_.-]+匹配email地址 |
* | 緊跟在它前面的單元應匹配零次或多次 | [0-9][0-9]*匹配至少一位數字,等價於[0-9]+,[azA-Z_]+[a-zA-Z_0-9]*匹配C語言的標識符 |
{N} | 緊跟在它前面的單元應精確匹配N次 | [1-9][0-9]{2}匹配從100到999的整數 |
{N,} | 緊跟在它前面的單元應匹配至少N次 | [1-9][0-9]{2,}匹配三位以上(含三位)的整數 |
{,M} | 緊跟在它前面的單元應匹配最多M次 | [0-9]{,1}相當於[0-9]? |
{N,M} | 緊跟在它前面的單元應匹配至少N次,最多M次 | [0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}匹配IP地址 |
位置限定符
字符 | 含義 | 舉例 |
---|---|---|
^ | 匹配行首的位置 | ^Content匹配位於一行開頭的Content |
$ | 匹配行末的位置 | ;$匹配位於一行結尾的;號,^$匹配空行 |
\ < | 匹配單詞開頭的位置 | <th匹配… this,但不匹配ethernet、tenth |
\ > | 匹配單詞結尾的位置 | p>匹配leap …,但不匹配parent、sleepy |
\b | 匹配單詞開頭或結尾的位置 | \bat\b匹配… at …,但不匹配cat、atexit、batch |
\B | 匹配非單詞開頭和結尾的位置 | \Bat\B匹配battery,但不匹配… attend、hat… |
其它特殊字符
字符 | 含義 | 舉例 |
---|---|---|
\ | 轉義字符,普通字符轉義爲特殊字符,特殊字符轉義爲普通字符 | 普通字符<寫成<表示單詞開頭的位置,特殊字符.寫成.以及\寫成\就當作普通字符來匹配 |
() | 將正則表達式的一部分括起來組成一個單元,可以對整個單元使用數量限定符 | ([0-9]{1,3}.){3}[0-9]{1,3}匹配IP地址 |
| | 連接兩個子表達式,表示或的關係 | n(o|either)匹配no或neither |
測試
首先準備文件 regular,內容爲:
[email protected]
[email protected]
[email protected]
[email protected]
3eedf_ddd@22_qq.com
12.34.55.78
123.456.67.8
1234.45.45.4566
0.0.0.0
grep 是一種查找過濾工具,正則表達式在 grep 中用來查找符合模式的字符串。
grep的正則表達式有Basic和Extended兩種規範,默認爲Basic
egrep 相當於grep -E,表示採用 Extended 正則表達式語法。
另外還有 fgrep 命令,相當於 grep -F,表示只搜索固定字符串而不搜索正則表達式模式,不會按正則表達式的語法解釋後面的參數。
egrep ‘[0-9a-z]’ regular 匹配數字和小寫字母
egrep ‘[^0-9]’ regular 匹配除了數字外的所有字符
egrep ‘[0-9]{1,3}’ regular 匹配 1-3 個數字
egrep ‘^[0-9]{1,3}’ regular 匹配 1-3 個數字開頭的行
egrep ‘[0-9]{1,3}$’ regular 匹配 1-3 個數字結尾的行
egrep ‘^[a-zA-Z0-9_.-]+@[a-zA-Z0-9_.-]+.[a-zA-Z0-9_.-]+’ regular 匹配電子郵箱
egrep ‘^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}’ regular 匹配 IP 地址