正則表達式元字符
正則表達式中有兩種基本元素:
-
以字面值或變量表示的值(如.代表任意單個字符)。
-
操作符(如*代表將前面的字符重復任意次)。
元字符匯總
特殊字符 |
用途 |
. |
匹配除換行符以外的任意單個字符。在awk中,句點也能匹配換行符。 |
* |
匹配任意一個(包括零個)在它面前的字符(包括由正則表達式指定的字符) |
[…] |
匹配方括號中的字符類中的任意一個。如果方括號中第一個字符為脫字符號(^),則表示否定匹配,即匹配出了換行符和類中列出的哪些字符以外的所有字符。在awk中,也匹配換行符。連字符(-)用於表示字符的范圍。如果類中的第一個字符為右方括號(])則表示它是類的成員。所有其他的元字符在被指定為類中成員時都會失去它們原來的含義。 |
^ |
如果作為正則表達式的第一個字符,則表示匹配行的開始。在awk中匹配字符串的開始,即使字符串包含嵌入的換行符。 |
$ |
如果作為正則表達式的最后一個字符,則表示匹配行的結尾。在awk中匹配字符串的結尾,即使字符串包含嵌入的換行符。 |
\{n,m\} |
匹配它前面某個范圍內單個字符出現的次數(包括由正則表達式指定的字符)。\{n,m\}將匹配n次出現,\{n,\}至少匹配n次出現,而且\{n,m\}匹配n和m之間的任意次出現。 |
\ |
轉意隨后的特殊字符。 |
+ |
匹配前面的正則表達式的一次或多次出現。 |
? |
匹配前面的正則表達式的零次或一次出現。 |
| |
指定可以匹配其前面的或后面的正則表達式。 |
() |
對正則表達式分組 |
{n,m} |
匹配它前面某個范圍內單個字符出現的次數(包括由正則表達式指定的字符)。{n}表示匹配n次出現,{n,}表示至少匹配n次出現,{n,m}匹配n和m之間的任意次出現。 |
普遍存在的反斜杠
元字符反斜杠(/)將元字符轉換成普通字符(或將普通字符轉換成元字符)。它強制將任意元字符解釋為普通字符,一邊匹配該字符本身。
在sed中,使用反斜杠將一組普通字符轉意為元字符。
如 \(\) \{\} \n
字符類
字符類是對通配符概念的改進。我們可以列出要匹配的字符,而不是匹配特殊位置的任意字符。使用方括號元字符([])將字符列表括起來,其中每個字符占據一個位置。
注意:在方括號中元字符會失去它們的含義。
如[Ww]hat可以匹配what或者What
字符類中的的特殊字符:
字符 |
功能 |
\ |
轉義任意特殊字符(只用於awk中) |
- |
當它不再第一個或最后一個位置時,表示一個范圍。 |
^ |
僅當在第一個位置時表示反轉匹配。 |
反斜杠只在awk中是特殊的,因此可以使用字符類"[a\]1]"以匹配一個a、一個]或一個1。
如果閉括號(])是作為類中的第一個字符出現(或者是脫字符后的第一個字符),那么它就被解釋為類的一個成員。如果連字符在一個類中是第一個或最后一個字符,則失去其特殊含義。因此,為了匹配算術操作符,我們在下面的實例中將連字符(-)放在第一位:
[-+*/]
使用正則表達式匹配下面的日期,該日期可能有下面兩種格式:
MM-DD-YY
MM/DD/YY
下面的正則表達式指示每個字符位置可能的樹枝范圍:
[0-9][0-9][-/][0-3][0-9][-/][0-9][0-9]
"-"或"/"都可能是定界符。在第一個位置防止連字符確保它在字符類中解釋為字面意義,即作為一個連字符,而不是指示一個范圍。
排除字符類
通常,字符類包括在哪個位置想要匹配的所有字符。在類中作為第一個字符的脫字符(^)將類中所有字符都排除在被匹配之外。相反,除換行符以外沒有在列的方括號中的任意字符都將被匹配。
下面的模式將匹配任意非數字字符:
[^0-9]
它匹配字面表中所有的大寫和小寫字面以及所有特殊字符,例如標點符號。
POSIX字符類補充
POSIX標准對正則表達式字符和操作符的含義進行了形式化。這種標准定義了兩類正則表達式:基本的正則表達式(BRE),grep和sed使用這種正則表達式;擴展的正則表達式,egrep和awk使用這種正則表達式。
POSIX還改變了常用的屬於,我們一直成為"字符類"的東西在POSIX標准中成為"括號表達式"。在括號表達式中,出了字面字符(例如a, !等)以外,還可以由其他標記。如:
-
字符類。由[:和:]包圍的關鍵字組成的POSIX字符類。關鍵字描述了不同的字符類,如文字字符類,控制字符等等。
-
整理復合。整理復合是多字符的序列。表示這些字符應該被看作是一個單元,它由[,和.]包圍的字符組成。
-
等價類。等價類列出了應該看作是等價的字符集,它由地區化的字符元素(有[=和=]包圍)組成。
所有這3種結果都必須出現在括號表達式的方括號中。例如[[:alpha:]!]匹配任意單個字幕字符或感嘆號,[[.ch.]]匹配整理元素ch,但不止匹配字幕c或字幕h。
POSIX字符類:
[:alnum:] |
可打印的字符(包括空白字符) |
[:alpha:] |
字母字符 |
[:blank:] |
空格和制表符 |
[:cntrl:] |
控制字符 |
[:digit:] |
數字字符 |
[:graph:] |
可打印和可見的(非空格)字符 |
[:lower:] |
小寫字符 |
[:print:] |
可打印的字符(包括空包字符) |
[:punct:] |
標點符號字符 |
[:space:] |
空白字符 |
[:upper:] |
大寫字符 |
[:xdigit:] |
十六進制數字 |
定位元字符
有兩個元字符用於指定字符串出現在行首或行末的上下文。脫字符^表示行開始,$表示行結束。
可以使用兩個聯系的定位元字符來匹配空行,即:
^$
可以使用這種模式計算文件中的空行數,在grep中使用計數選項-c:
# grep –c '^$' ch04
5
如果想使用sed來刪除空行,那么這個正則表達式很有用。下面的正則表達式可以用於匹配空行,即使其中包含空格:
^□*$
同樣,可以使用以下表達式匹配整個行:
^.*$
在sed(和grep)中,只有當"^"和"$"分別出現在正則表達式的開始或結尾才是特殊的。因此"^abc" 意味着 "匹配只處於行開始處的字母a、b和c",而"ab^c"以為着"匹配處於行的任意位置的a、b、字面意義的^,然后是c"。這對於"$"同樣適用。
在awk中則不同,"^"和"$"總是特殊的,即使它們可能使編寫的正則表達式不匹配任何東西。可以說,在awk中,當想要匹配字面"^"或"$"時,不管它處於正則表達式的什么位置都應該使用反斜杠對其進行轉義。
字符的跨度
在grep和sed中使用\{和\}。POSIX egrep 和 POSIX awk使用{和}。在任何情況下,大括號包圍一個或兩個參數。
\{n,m\}
n和m是0到255之間的整數。如果只指定\{n\}本身,那么將精確匹配前面的字符或正則表達式的n次出現。如果指定\{n,m\},那么就匹配出現的次數為n和m之間的任意次數。
選擇性操作
豎線(|)元字符是元字符擴展集的一部分,用於指定正則表達式的聯合。如果某行匹配其中的一個正則表達式,那么它就匹配該模式。
分組操作
圓括號()用於對正則表達式進行分組並設置優先級。它們是元字符擴展集的一部分。假設在文本文件中將公司的名稱為"BigOne"或"BigOneComputer",使用正則表達式:
BigOne(Computer)?
將匹配字符串"BigOne"本身或者后面跟有一個字符串"□Computer"的形式。同樣,有些屬於有時會用全拼,有時會用縮寫、則可以使用:
# egrep "Lab(oratorie)?s" mail.list
Bell Laboratories, Lucent Technologies
Bell Labs
可以用豎線和圓括號來對選擇性操作進行分組。在下面的示例中,使用它來指定單詞"company"的單數或復數匹配。
compan(y|ies)
注意:大多數sed和grep 的版本中不能對加圓括號的一組字符應用數量詞,但是在egrep和awk的所有版本都是可以的。
限制范圍
一個正則表達式為:
A.*Z
匹配的結果為
All of us, including Zippy, our dog
All of us, including Zippy and Ziggy
All of us, including Zippy and Ziggy and Zelda
下划線的字符串表示匹配的字符串,即.*在每種情況下都會匹配可能的最長的范圍。
正則表達式嘗試匹配最長的字符串,這可能會引起意想不到的問題。例如,下面的正則表達式與引號中的任意個字符匹配:
".*"
輸入字符串為:
.Se "Appendix" "Full Progarm Listings."
要匹配第一個參數,可以用下面的正則表達式來描述:
\.Se ".*"
然而,因為模式中的第二個引號與該行上的最后一個引號匹配,所以它結束匹配整個行。如果知道參數的個數,那么可以對每個進行說明:
\.Se ".*" ".*"
雖然這種方法可以像期望的那樣工作,但是每行也許不會有相同書目的參數,省略你只想要第一個參數。這里有一個匹配兩個引號之間最短范圍的正則表達式:
"[^ "]*"
它匹配引號並且后面跟有任意個字符的情況,但它不匹配引號后面跟有引號的情況。
其他一些正則
國家的縮寫 |
□[A-Z][A-Z]□ |
HTML代碼 |
<[^ >]*> |
匹配空行 |
^$ |
匹配整行 |
^.*$ |
匹配一個或多個空格(空內容的行) |
□□* |