天天看點

正規表達式 - 文法

正規表達式(regular expression)描述了一種字元串比對的模式(pattern),可以用來檢查一個串是否含有某種子串、将比對的子串替換或者從某個串中取出符合某個條件的子串等。

例如:

runoo+b,可以比對 runoob、runooob、runoooooob 等,+ 号代表前面的字元必須至少出現一次(1次或多次)。

runoo*b,可以比對 runob、runoob、runoooooob 等,* 号代表前面的字元可以不出現,也可以出現一次或者多次(0次、或1次、或多次)。

colou?r 可以比對 color 或者 colour,? 問号代表前面的字元最多隻可以出現一次(0次、或1次)。

構造正規表達式的方法和建立數學表達式的方法一樣。也就是用多種元字元與運算符可以将小的表達式結合在一起來建立更大的表達式。正規表達式的元件可以是單個的字元、字元集合、字元範圍、字元間的選擇或者所有這些元件的任意組合。

正規表達式是由普通字元(例如字元 a 到 z)以及特殊字元(稱為"元字元")組成的文字模式。模式描述在搜尋文本時要比對的一個或多個字元串。正規表達式作為一個模闆,将某個字元模式與所搜尋的字元串進行比對。

普通字元包括沒有顯式指定為元字元的所有可列印和不可列印字元。這包括所有大寫和小寫字母、所有數字、所有标點符号和一些其他符号。

字元

描述

[ABC]

比對 [...] 中的所有字元,例如 [aeiou] 比對字元串 "google runoob taobao" 中所有的 e o u a 字母。

正規表達式 - 文法

[^ABC]

比對除了 [...] 中字元的所有字元,例如 [^aeiou] 比對字元串 "google runoob taobao" 中除了 e o u a 字母的所有字母。

正規表達式 - 文法

[A-Z]

[A-Z] 表示一個區間,比對所有大寫字母,[a-z] 表示所有小寫字母。

正規表達式 - 文法

.

比對除換行符(\n、\r)之外的任何單個字元,相等于 [^\n\r]。

正規表達式 - 文法

[\s\S]

比對所有。\s 是比對所有空白符,包括換行,\S 非空白符,不包括換行。

正規表達式 - 文法

\w

比對字母、數字、下劃線。等價于 [A-Za-z0-9_]

正規表達式 - 文法

修飾符:

比對文本:

非列印字元也可以是正規表達式的組成部分。下表列出了表示非列印字元的轉義序列:

\cx

比對由x指明的控制字元。例如, \cM 比對一個 Control-M 或回車符。x 的值必須為 A-Z 或 a-z 之一。否則,将 c 視為一個原義的 'c' 字元。

\f

比對一個換頁符。等價于 \x0c 和 \cL。

\n

比對一個換行符。等價于 \x0a 和 \cJ。

\r

比對一個回車符。等價于 \x0d 和 \cM。

\s

比對任何空白字元,包括空格、制表符、換頁符等等。等價于 [ \f\n\r\t\v]。注意 Unicode 正規表達式會比對全角空格符。

\S

比對任何非空白字元。等價于 [^ \f\n\r\t\v]。

\t

比對一個制表符。等價于 \x09 和 \cI。

\v

比對一個垂直制表符。等價于 \x0b 和 \cK。

所謂特殊字元,就是一些有特殊含義的字元,如上面說的 runoo*b 中的 *,簡單的說就是表示任何字元串的意思。如果要查找字元串中的 * 符号,則需要對 * 進行轉義,即在其前加一個 \,runo\*ob 比對字元串 runo*ob。

許多元字元要求在試圖比對它們時特别對待。若要比對這些特殊字元,必須首先使字元"轉義",即,将反斜杠字元\ 放在它們前面。下表列出了正規表達式中的特殊字元:

特别字元

$

比對輸入字元串的結尾位置。如果設定了 RegExp 對象的 Multiline 屬性,則 $ 也比對 '\n' 或 '\r'。要比對 $ 字元本身,請使用 \$。

( )

标記一個子表達式的開始和結束位置。子表達式可以擷取供以後使用。要比對這些字元,請使用 \( 和 \)。

*

比對前面的子表達式零次或多次。要比對 * 字元,請使用 \*。

+

比對前面的子表達式一次或多次。要比對 + 字元,請使用 \+。

比對除換行符 \n 之外的任何單字元。要比對 . ,請使用 \. 。

[

标記一個中括号表達式的開始。要比對 [,請使用 \[。

?

比對前面的子表達式零次或一次,或指明一個非貪婪限定符。要比對 ? 字元,請使用 \?。

\

将下一個字元标記為或特殊字元、或原義字元、或向後引用、或八進制轉義符。例如, 'n' 比對字元 'n'。'\n' 比對換行符。序列 '\\' 比對 "\",而 '\(' 則比對 "("。

^

比對輸入字元串的開始位置,除非在方括号表達式中使用,當該符号在方括号表達式中使用時,表示不接受該方括号表達式中的字元集合。要比對 ^ 字元本身,請使用 \^。

{

标記限定符表達式的開始。要比對 {,請使用 \{。

|

指明兩項之間的一個選擇。要比對 |,請使用 \|。

限定符用來指定正規表達式的一個給定元件必須要出現多少次才能滿足比對。有 * 或 + 或 ? 或 {n} 或 {n,} 或 {n,m} 共6種。

正規表達式的限定符有:

比對前面的子表達式零次或多次。例如,zo* 能比對 "z" 以及 "zoo"。* 等價于{0,}。

比對前面的子表達式一次或多次。例如,'zo+' 能比對 "zo" 以及 "zoo",但不能比對 "z"。+ 等價于 {1,}。

比對前面的子表達式零次或一次。例如,"do(es)?" 可以比對 "do" 、 "does" 中的 "does" 、 "doxy" 中的 "do" 。? 等價于 {0,1}。

{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?'。請注意在逗号和兩個數之間不能有空格。

以下正規表達式比對一個正整數,[1-9]設定第一個數字不是 0,[0-9]* 表示任意多個數字:

正規表達式 - 文法

請注意,限定符出現在範圍表達式之後。是以,它應用于整個範圍表達式,在本例中,隻指定從 0 到 9 的數字(包括 0 和 9)。

這裡不使用 + 限定符,因為在第二個位置或後面的位置不一定需要有一個數字。也不使用 ? 字元,因為使用 ? 會将整數限制到隻有兩位數。

如果你想設定 0~99 的兩位數,可以使用下面的表達式來至少指定一位但至多兩位數字。

上面的表達式的缺點是,隻能比對兩位數字,而且可以比對 0、00、01、10 99 的章節編号仍隻比對開頭兩位數字。

改進下,比對 1~99 的正整數表達式如下:

* 和 + 限定符都是貪婪的,因為它們會盡可能多的比對文字,隻有在它們的後面加上一個 ? 就可以實作非貪婪或最小比對。

例如,您可能搜尋 HTML 文檔,以查找在 h1 标簽内的内容。HTML 代碼如下:

貪婪:下面的表達式比對從開始小于符号 (<) 到關閉 h1 标記的大于符号 (>) 之間的所有内容。

正規表達式 - 文法

非貪婪:如果您隻需要比對開始和結束 h1 标簽,下面的非貪婪表達式隻比對 <h1>。

正規表達式 - 文法

也可以使用以下正規表達式來比對 h1 标簽,表達式則是:

正規表達式 - 文法

通過在 *、+ 或 ? 限定符之後放置 ?,該表達式從"貪婪"表達式轉換為"非貪婪"表達式或者最小比對。

定位符使您能夠将正規表達式固定到行首或行尾。它們還使您能夠建立這樣的正規表達式,這些正規表達式出現在一個單詞内、在一個單詞的開頭或者一個單詞的結尾。

定位符用來描述字元串或單詞的邊界,^ 和 $ 分别指字元串的開始與結束,\b 描述單詞的前或後邊界,\B 表示非單詞邊界。

正規表達式的定位符有:

比對輸入字元串開始的位置。如果設定了 RegExp 對象的 Multiline 屬性,^ 還會與 \n 或 \r 之後的位置比對。

比對輸入字元串結尾的位置。如果設定了 RegExp 對象的 Multiline 屬性,$ 還會與 \n 或 \r 之前的位置比對。

\b

比對一個單詞邊界,即字與空格間的位置。

\B

非單詞邊界比對。

注意:不能将限定符與定位符一起使用。由于在緊靠換行或者單詞邊界的前面或後面不能有一個以上位置,是以不允許諸如 ^* 之類的表達式。

若要比對一行文本開始處的文本,請在正規表達式的開始使用 ^ 字元。不要将 ^ 的這種用法與中括号表達式内的用法混淆。

若要比對一行文本的結束處的文本,請在正規表達式的結束處使用 $ 字元。

若要在搜尋章節标題時使用定位點,下面的正規表達式比對一個章節标題,該标題隻包含兩個尾随數字,并且出現在行首:

真正的章節标題不僅出現行的開始處,而且它還是該行中僅有的文本。它既出現在行首又出現在同一行的結尾。下面的表達式能確定指定的比對隻比對章節而不比對交叉引用。通過建立隻比對一行文本的開始和結尾的正規表達式,就可做到這一點。

比對單詞邊界稍有不同,但向正規表達式添加了很重要的能力。單詞邊界是單詞和空格之間的位置。非單詞邊界是任何其他位置。下面的表達式比對單詞 Chapter 的開頭三個字元,因為這三個字元出現在單詞邊界後面:

\b 字元的位置是非常重要的。如果它位于要比對的字元串的開始,它在單詞的開始處查找比對項。如果它位于字元串的結尾,它在單詞的結尾處查找比對項。例如,下面的表達式比對單詞 Chapter 中的字元串 ter,因為它出現在單詞邊界的前面:

下面的表達式比對 Chapter 中的字元串 apt,但不比對 aptitude 中的字元串 apt:

字元串 apt 出現在單詞 Chapter 中的非單詞邊界處,但出現在單詞 aptitude 中的單詞邊界處。對于 \B 非單詞邊界運算符,位置并不重要,因為比對不關心究竟是單詞的開頭還是結尾。

用圓括号 () 将所有選擇項括起來,相鄰的選擇項之間用 | 分隔。

() 表示捕獲分組,() 會把每個分組裡的比對的值儲存起來,

多個比對值可以通過數字 n 來檢視(n 是一個數字,表示第 n 個捕獲組的内容)。

正規表達式 - 文法
正規表達式 - 文法

但用圓括号會有一個副作用,使相關的比對會被緩存,此時可用 ?: 放在第一個選項前來消除這種副作用。

其中 ?: 是非捕獲元之一,還有兩個非捕獲元是 ?= 和 ?!,這兩個還有更多的含義,前者為正向預查,在任何開始比對圓括号内的正規表達式模式的位置來比對搜尋字元串,後者為負向預查,在任何開始不比對該正規表達式模式的位置來比對搜尋字元串。

exp1(?=exp2):查找 exp2 前面的 exp1。

正規表達式 - 文法

(?<=exp2)exp1:查找 exp2 後面的 exp1。

正規表達式 - 文法

exp1(?!exp2):查找後面不是 exp2 的 exp1。

正規表達式 - 文法

(?<!exp2)exp1:查找前面不是 exp2 的 exp1。

正規表達式 - 文法
更多内容可以參考:正規表達式的先行斷言(lookahead)和後行斷言(lookbehind)

對一個正規表達式模式或部分模式兩邊添加圓括号将導緻相關比對存儲到一個臨時緩沖區中,所捕獲的每個子比對都按照在正規表達式模式中從左到右出現的順序存儲。緩沖區編号從 1 開始,最多可存儲 99 個捕獲的子表達式。每個緩沖區都可以使用 \n 通路,其中 n 為一個辨別特定緩沖區的一位或兩位十進制數。

可以使用非捕獲元字元 ?:、?= 或 ?! 來重寫捕獲,忽略對相關比對的儲存。

反向引用的最簡單的、最有用的應用之一,是提供查找文本中兩個相同的相鄰單詞的比對項的能力。以下面的句子為例:

上面的句子很顯然有多個重複的單詞。如果能設計一種方法定位該句子,而不必查找每個單詞的重複出現,那該有多好。下面的正規表達式使用單個子表達式來實作這一點:

查找重複的單詞:

var str = "Is is the cost of of gasoline going up up";

var patt1 = /\b([a-z]+) \1\b/ig;

document.write(str.match(patt1));

捕獲的表達式,正如 [a-z]+ 指定的,包括一個或多個字母。正規表達式的第二部分是對以前捕獲的子比對項的引用,即,單詞的第二個比對項正好由括号表達式比對。\1 指定第一個子比對項。

單詞邊界元字元確定隻檢測整個單詞。否則,諸如 "is issued" 或 "this is" 之類的詞組将不能正确地被此表達式識别。

正規表達式後面的全局标記 g 指定将該表達式應用到輸入字元串中能夠查找到的盡可能多的比對。

表達式的結尾處的不區分大小寫 i 标記指定不區分大小寫。

多行标記指定換行符的兩邊可能出現潛在的比對。

反向引用還可以将通用資源訓示符 (URI) 分解為其元件。假定您想将下面的 URI 分解為協定(ftp、http 等等)、域位址和頁/路徑:

下面的正規表達式提供該功能:

輸出所有比對的資料:

var str = "http://www.runoob.com:80/html/html-tutorial.html";

var patt1 = /(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)/;

arr = str.match(patt1);

for (var i = 0; i < arr.length ; i++) {

document.write(arr[i]);

document.write("<br>");

}

第三行代碼 str.match(patt1) 傳回一個數組,執行個體中的數組包含 5 個元素,索引 0 對應的是整個字元串,索引 1 對應第一個比對符(括号内),以此類推。

第一個括号子表達式捕獲 Web 位址的協定部分。該子表達式比對在冒号和兩個正斜杠前面的任何單詞。

第二個括号子表達式捕獲位址的域位址部分。子表達式比對非 : 和 / 之後的一個或多個字元。

第三個括号子表達式捕獲端口号(如果指定了的話)。該子表達式比對冒号後面的零個或多個數字。隻能重複一次該子表達式。

最後,第四個括号子表達式捕獲 Web 位址指定的路徑和 / 或頁資訊。該子表達式能比對不包括 # 或空格字元的任何字元序列。

将正規表達式應用到上面的 URI,各子比對項包含下面的内容:

第一個括号子表達式包含 http

第二個括号子表達式包含 www.runoob.com

第三個括号子表達式包含 :80

第四個括号子表達式包含 /html/html-tutorial.html