Regex是一個描述字元模式的對象。
JavaScript的RegExp對象和String對象定義了使用Regex來執行強大的模式比對和文本檢索與替換函數的方法.
在JavaScript中,Regex是由一個RegExp對象表示的.當然,可以使用一個RegExp()建構函式來建立RegExp對象,也可以用JavaScript
Regex直接量也被定義為包含在一對斜杠(/)之間的字元.所以,JavaScript可能會包含如下的代碼:
1 var pattern = /s$/;
這行代碼建立一個新的RegExp對象,並將它賦給變數parttern.這個特殊的RegExp對象和所有以字母"s"結尾的字串都匹配.用RegExp()也可以定義 一個等價的Regex,代碼如下:
1 var pattern = new RegExp("s$");
無論是用Regex直接量還是用建構函式RegExp(),建立一個RegExp對象都是比較容易的.較為困難的任務是用Regex文法來描述字元的模式.
JavaScript採用的是Perl語言Regex文法的一個相當完整的子集.
Regex的模式規範是由一系列字元構成的.大多數字元(包括所有字母數字字元)描述的都是按照字面意思進行匹配的字元.這樣說來,Regex/java/就和所有包含子串 "java" 的字串相匹配.雖然Regex中的其它字元不是按照字面意思進行匹配的,但它們都具有特殊的意義.Regex /s$/ 包含兩個字元.第一個特殊字元 "s" 是按照字面意思與自身相匹配.第二個字元 "$" 是一個特殊字元,它所匹配的是字串的結尾.所以Regex /s$/ 匹配的就是以字母 "s" 結尾 的字串.
下面詳細講解.
我們已經發現了,在Regex中所有的字母字元和數字都是按照字面意思與自身相匹配的.JavaScript的Regex還通過以反斜線(/)開頭的逸出序列支援某些非字母字元.例如,序列 "/n" , 在字串中匹配的是一個直接量分行符號.在Regex中,許多標點符號都有特殊的含義.下面是這些字元和它們的含義:
Regex的直接量字元
字元 匹配
________________________________
字母數字字元 含義
/ f 換頁符
/ n 分行符號
/ r 斷行符號
/ t 定位字元
/ v 垂直定位字元
/ / 一個 / 直接量
/ / 一個 / 直接量
/ . 一個 . 直接量
/ * 一個 * 直接量
/ + 一個 + 直接量
/ ? 一個 ? 直接量
/ | 一個 ( 直接量
/ ) 一個 ) 直接量
/ [ 一個 [ 直接量
/ ] 一個 ] 直接量
/ { 一個 { 直接量
/ } 一個 } 直接量
/ XXX 由十進位數 XXX 指定的ASCII碼字元
/ Xnn 由十六進位數 nn 指定的ASCII碼字元
/ cX 控制字元^X. 例如, /cI等價於
/t, /cJ等價於 /n
___________________________________________________
如果想在Regex中使用特殊的標點符號,必須在它們之前加上一個 "/" .
2.字元類
將單獨的直接符放進中括弧內就可以組合成字元類.一個字元類和它所包含的任何一個字元都匹配,所以Regex / [abc] / 和字母 "a" , "b" , "c" 中的任何一個都匹配.另外還可以定義否定字元類,這些類匹配的是除那些包含在中括弧之內的字元外的所有字元.定義否定字元尖時,要將一個 ^ 符號作為從左中括弧算起的第 一個字元.Regex的集合是 / [a-zA-z0-9] / .由於某些字元類非常常用,所以JavaScript的Regex文法包含一些特殊字元和逸出序列來表示這些常用的類.例如, /s 匹配的是空格符,定位字元和其它空白符, /s匹配的則是空白符之外的任何字元.
Regex的字元類
字元 匹配
____________________________________________________
[...] 位於括弧之內的任一字元
[^...] 不在括弧之中的任一字元
.
除了分行符號之外的任一字元,等價於[^/n]
/w 任何單字字元,
等價於[a-zA-Z0-9]
/W
任何非單字字元,等價於[^a-zA-Z0-9]
/s 任何空白符,等價於[/ t
/ n / r / f / v]
/S 任何非空白符,等價於[^/
t / n / r / f / v]
/d 任何數字,等價於[0-9]
/D
除了數字之外的任何字元,等價於[^0-9]
[/b] 一個退格直接量(特例)
________________________________________________________________
3.複製
用以上的正則表式的文法,可以把兩位元描述成 / / d / d /,把四位元描述成 / /d / d / d / d /.但我們還沒有一種方法可以用來描述具有任意多數位的數字或者是一個字串.這個串由三個字元以及跟隨在字母之後的一位元字構成.這些複雜的模式使用的Regex文法指定了該運算式中每個元素要重複出現的次數.指定複製的字元總是出現在它們所作用的模式後面.由於某種複製類型相當常用.所以有一些特殊的字元專門用於表示它們.例如:
+號匹配的就是複製前一模式一次
或多次的模式.下面的表列出了複製文法.先看一個例子:
//d{2, 4}/ //匹配2到4間的數字.
//w{3} /d?/ //匹配三個單字字元和一個任意的數字.
//s+java/s+/ //匹配字串"java"
,並且該串前後可以有一個或多個空格.
/[^"] * / //匹配零個或多個非引號字元.
Regex的複製字元
字元 含義
__________________________________________________________________
{n, m} 匹配前一項至少n次,但是不能超過m次
{n, } 匹配前一項n次,或者多次
{n} 匹配前一項恰好n次
? 匹配前一項0次或1次,也就是說前一項是可選的. 等價於 {0, 1}
+ 匹配前一項1次或多次,等價於{1,}
* 匹配前一項0次或多次.等價於{0,}
___________________________________________________________________
4.選擇,分組和引用
Regex的文法還包括指定選擇項,對子運算式分組和引用前一子運算式的特殊字元.字元| 用於分隔供選擇的字元.例如:
/ab|cd|ef/ 匹配的是字串 "ab",或者是
字串 "cd",又或者 "ef". //d{3}|[a-z]{4}/
匹配的是要麼是一個三位元,要麼是四個小寫字母.在Regex中括弧具有幾種作用.它的主要作用是把單獨的項目分組
成子運算式,以便可以像處理一個獨立的單元那種用 *、+或? 來處理那些項目.例如: /java(script) ?/
匹配的是字串 "java",其後既可以有 "script",也可以沒有. /
(ab|cd) + |ef) / 匹配的既可以是字串 "ef",也可以是字串"ab" 或者 "cd" 的一次或多次重複.
在Regex中,括弧的第二個用途是在完整的模式中定義子模式。當一個Regex成功地和目標字串相匹配時,可以從目標串中抽出和括弧中的子模式相匹配
的部分.例如,假定我們正在檢索的模式是一個或多個字母后面跟隨一位或多位元字,那麼我們可以使用模式 / [a-z] + /
d+/.但是由於假定我們真正關心的是每個匹配
尾部的數字,那麼如果我們將模式的數字部分放在括弧中 (/ [a-z] + (/d+)/)
,我們就可以從所檢索到的任何匹配中抽取數字了,之後我們會對此進行解析的.
代括弧的子運算式的另一個用途是,允許我們在同一Regex的後面引用前面的子運算式.這是通過在字串 /
後加一位或多位元字來實現的.數字指的是代括弧的
子運算式在Regex中的位置.例如: /1 引用的是第一個代括弧的子運算式. /3
引用的是第三個代括弧的子運算式.注意,由於子運算式可以嵌套在其它子運算式中,
所以它的位置是被計數的左括弧的位置.
例如:在下面的Regex被指定為 /2:
/([Jj]ava([Ss]cript)) /sis /s (fun/w*) /
對Regex中前一子運算式的引用所指定的並不是那個子運算式的模式,而是與那個模式相匹配的文本.這樣,引用就不只是協助你輸入Regex的重複部分的快
捷方式了,它還實施了一條規約,那就是一個字串各個分離的部分包含的是完全相同的字元.例如:下面的Regex匹配的就是位於單引號或雙引號之內的所有字
符.但是,它要求開始和結束的引號匹配(例如兩個都是雙引號或者都是單引號):
/[' "] [^ ' "]*[' "]/
如果要求開始和結束的引號匹配,我們可以使用如下的引用:
/( [' "] ) [^ ' "]
* /1/
/1匹配的是第一個代括弧的子運算式所匹配的模式.在這個例子中,它實施了一種規約,那就是開始的引號必須和結束的引號相匹配.注意,如果反斜線後跟隨的數字比
代括弧的子運算式數多,那麼它就會被解析為一個十進位的逸出序列,而不是一個引用.你可以堅持使用完整的三個字元來表示逸出序列,這們就可以避免混淆了.例如,
使用 /044,而不是/44.下面是Regex的選擇、分組和引用字元:
字元 含義
____________________________________________________________________
|
選擇.匹配的要麼是該符號左邊的子運算式,要麼它右邊的子運算式
(...) 分組.將幾個項目分為一個單元.這個單元可由
*、+、?和|等符號使用,而且還可以記住和這個組匹配的字元以供此後引
用使用
/n
和第n個分組所匹配的字元相匹配.分組是括弧中的子運算式(可能是嵌套的).分組號是從左至右計數的左括弧數
____________________________________________________________________
5.指定匹配的位置
我們已經看到了,一個Regex中的許多元素才能夠匹配字串的一個字元.例如: /s
匹配的只是一個空白符.還有一些Regex的元素匹配的是字元之間寬度為
0的空間,而不是實際的字元例如: /b 匹配的是一個詞語的邊界,也就是處於一個/w字字元和一個/w非字字元之間的邊界.像/b
這樣的字元並不指定任何一個匹配了的
字串中的字元,它們指定的是匹配所發生的合法位置.有時我們稱這些元素為Regex的錨.因為它們將模式定位在檢索字串中的一個特定位置.最常用的錨元
素是 ^, 它使模式依賴於字串的開頭,而錨元素$則使模式定位在字串的末尾.
例如:要匹配詞 "javascript" ,我們可以使用Regex /^ javascript $/. 如果我們想檢索
"java" 這個詞自身 (不像在 "javascript" 中那樣作為首碼),那麼我們可以使
用模式 //s java /s /, 它要求在詞語java之前和之後都有空格.但是這樣作有兩個問題.第一: 如果
"java" 出現在一個字元的開頭或者是結尾.該模式就不會與之匹配,除
非在開頭和結尾處有一個空格. 第二:
當這個模式找到一個與之匹配的字元時,它返回的匹配的字串前端和後端都有空格,這並不是我們想要的.因此,我們使用詞語
的邊界 /b 來代替真正的空格符 /s 進行匹配. 結果運算式是 //b java /b/.
下面是Regex的錨字元:
字元 含義
____________________________________________________________________
^
匹配的是字元的開頭,在多行檢索中,匹配的是一行的開頭
$ 匹配的是字元的結尾,在多行檢索中,匹配的是一行的結尾
/b
匹配的是一個詞語的邊界.簡而言之就是位於字元/w 和 /w之間的位置(注意:[/b]匹配的是退格符)
/B
匹配的是非詞語的邊界的字元
_____________________________________________________________________
6.屬性
有關Regex的文法還有最後一個元素,那就是Regex的屬性,它說明的是進階模式比對的規則.和其它Regex文法不同,屬性是在
/ 符號之外說明的.即它
們不出現在兩個斜杠之間,而是位於第二個斜杠之後.javascript 1.2支援兩個屬性.屬性 i
說明模式比對應該是大小寫不敏感的.屬性 g 說明模式比對應該是全域的.也
就是說,應該找出被檢索的字串中所有的匹配.這兩種屬性聯合起來就可以執行一個全域的,大小寫不敏感的匹配.
例如: 要執行一個大小不敏感的檢索以找到詞語 "java" (或者是 "java" 、"JAVA"等)
的第一個具體值,我們可以使用大小不敏感的Regex //b java/b/i .如果要在
一個字串中找到 "java" 所有的具體值,我們還可以添加屬性 g, 即 //b java /b/gi .
以下是Regex的屬性:
字元 含義
_________________________________________
i
執行大小寫不敏感的匹配
g
執行一個全域的匹配,簡而言之,就是找到所有的匹配,而不是在找到第一個之後就停止了
_________________________________________
除屬性 g 和 i 之外,Regex就沒有其它像屬性一樣的特性了.如果將建構函式 RegExp 的靜態屬性
multiline 設定為 true ,那麼模式比對將以多行的模式進行.在這
種模式下,錨字元 ^ 和 $ 匹配的不只是檢索字串的開頭和結尾,還匹配檢索字串內部的一行的開頭和結尾.例如: 模式
/Java$/ 匹配的是 "Java",但是並不匹配
"Java/nis fun" .如果我們設定了 multiline 屬性,那麼後者也將被匹配:
RegExp.multiline = true;