有時候不知道要匹配多少字符。為了能適應這種不確定性,正則表達式支持限定符的概念。這些限定符可以指定正則表達式的一個給定組件必須要出現多少次才能滿足匹配。
下表給出了各種限定符及其含義的說明:
| 字符 | 描述 |
|---|---|
| * | 匹配前面的子表達式零次或多次。例如,zo* 能匹配z 以及zoo。 * 等價於{0,}。 |
| + | 匹配前面的子表達式一次或多次。例如,'zo+' 能匹配zo 以及zoo,但不能匹配z。 + 等價於{1,}。 |
| ? | 匹配前面的子表達式零次或一次。例如,do(es)? 可以匹配do 或does 中的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?'。請注意在逗號和兩個數之間不能有空格。 |
對一個很大的輸入文檔而言,章節數很輕易就超過九章,因此需要有一種方法來處理兩位數或者三位數的章節號。限定符就提供了這個功能。下面的JScript 正則表達式可以匹配具有任何位數的章節標題:
/Chapter [1-9][0-9]*/下面的VBScript 正則表達式執行同樣的匹配:
Chapter [1-9][0-9]*請注意限定符出現在範圍表達式之後。因此,它將應用於所包含的整個範圍表達式,在本例中,只指定了從0 到9 的數字。
這裡沒有使用'+' 限定符,因為第二位或後續位置上並不一定需要一個數字。同樣也沒有使用'?' 字符,因為這將把章節數限制為只有兩位數字。在'Chapter' 和空格字符之後至少要匹配一個數字。
如果已知章節數限制只有99 章,則可以使用下面的JScript 表達式來指定至少有一位數字,但不超過兩個數字。
/Chapter [0-9]{1,2}/對VBScript 可以使用下述正則表達式:
Chapter [0-9]{1,2}上述表達式的缺點是如果有一個章節號大於99,它仍只會匹配前兩位數字。另一個缺點是某些人可以創建一個Chapter 0,而且仍能匹配。一個更好的用來匹配兩位數的JScript 表達式如下:
/Chapter [1-9][0-9]?/或者
/Chapter [1-9][0-9]{0,1}/對VBScript 而言,下述表達式與上面等價:
Chapter [1-9][0-9]?或者
Chapter [1-9][0-9]{0,1} ' * '、 ' +'和' ?'限定符都稱之為貪婪的,也就是說,他們盡可能多地匹配文字。有時這根本就不是所希望發生的情況。有時則正好希望最小匹配。
例如,你可能要搜索一個HTML 文檔來查找一處包含在H1 標記中的章節標題。在文檔中該文字可能具有如下形式:
<H1>Chapter 1 – Introduction to Regular Expressions</H1>下面的表達式匹配從開始的小於號(<) 到H1 標記結束處的大於號之間的所有內容。
/<.*>/VBScript 的正則表達式為:
<.*>如果所要匹配的就是開始的H1 標記,則下述非貪婪地表達式就只匹配<H1>。
/<.*?>/或者
<.*?>通過在'*'、 '+' 或'?' 限定符後放置'?',該表達式就從貪婪匹配轉為了非貪婪或最小匹配。
到現在為止,所看到的示例都只考慮查找任何地方出現的章節標題。出現的任何一個字符串'Chapter' 後跟一個空格和一個數字可能是一個真正的章節標題,也可能是對其他章節的交叉引用。由於真正的章節標題總是出現在一行的開始,因此需要設計一個方法只查找標題而不查找交叉引用。
定位符提供了這個功能。定位符可以將一個正則表達式固定在一行的開始或結束。也可以創建只在單詞內或只在單詞的開始或結尾處出現的正則表達式。下表包含了正則表達式及其含義的列表:
| 字符 | 描述 |
|---|---|
| ^ | 匹配輸入字符串的開始位置。如果設置了RegExp對象的Multiline屬性,^ 也匹配'/n' 或'/r' 之後的位置。 |
| $ | 匹配輸入字符串的結束位置。如果設置了RegExp對象的Multiline屬性,$ 也匹配'/n' 或'/r' 之前的位置。 |
| /b | 匹配一個單詞邊界,也就是指單詞和空格間的位置。 |
| /B | 匹配非單詞邊界。 |
不能對定位符使用限定符。因為在一個換行符或者單詞邊界的前面或後面不會有連續多個位置,因此諸如'^*' 的表達式是不允許的。
要匹配一行文字開始位置的文字,請在正則表達式的開始處使用'^' 字符。不要把'^' 的這個語法與其在括號表達式中的語法弄混。它們的語法根本不同。
要匹配一行文字結束位置的文字,請在正則表達式的結束處使用'$' 字符。
要在查找章節標題時使用定位符,下面的JScript 正則表達式將匹配位於一行的開始處最多有兩個數字的章節標題:
/^Chapter [1-9][0-9]{0,1}/VBScript 中相同功能的正則表達式如下:
^Chapter [1-9][0-9]{0,1}一個真正的章節標題不僅出現在一行的開始,而且這一行中也僅有這一個內容,因此,它必然也位於一行的結束。下面的表達式確保所指定的匹配只匹配章節而不會匹配交叉引用。它是通過創建一個只匹配一行文字的開始和結束位置的正則表達式來實現的。
/^Chapter [1-9][0-9]{0,1}$/對VBScript 則使用:
^Chapter [1-9][0-9]{0,1}___FCKpd___16quot;匹配單詞邊界有少許不同,但卻給正則表達式增加了一個非常重要的功能。單詞邊界就是單詞和空格之間的位置。非單詞邊界就是其他任何位置。下面的JScript 表達式將匹配單詞'Chapter' 的前三個字符,因為它們出現在單詞邊界後:
//bCha/對VBScript 為:
/bCha這裡'/b' 操作符的位置很關鍵。如果它位於要匹配的字符串的開始,則將查找位於單詞開頭處的匹配;如果它位於改字符串的末尾,則查找位於單詞結束處的匹配。例如,下面的表達式將匹配單詞'Chapter' 中的'ter',因為它出現在單詞邊界之前:
/ter/b/以及
ter/b下面的表達式將匹配'apt',因為它位於'Chapter' 中間,但不會匹配'aptitude' 中的'apt':
//Bapt/以及
/Bapt這是因為在單詞'Chapter' 中'apt' 出現在非單詞邊界位置,而在單詞'aptitude' 中位於單詞邊界位置。非單詞邊界操作符的位置不重要,因為匹配與一個單詞的開頭或結尾無關。