JavaScript的RegExp對象和String對象定義了使用Regex來執行強大的模式比對和文本檢索與替換函數的方法.
在JavaScript中,Regex是由一個RegExp對象表示的.當然,可以使用一個RegExp()建構函式來建立RegExp對象,也可以用 JavaScript 1.2中的新添加的一個特殊文法來建立RegExp對象.就像字串直接量被定義為包含在引號內的字元一樣,Regex直接量也被定義為包含在一對斜杠 (/)之間的字元.所以,JavaScript可能會包含如下的代碼:
var pattern = /s$/;
這行代碼建立一個新的RegExp對象,並將它賦給變數parttern.這個特殊的RegExp對象和所有以字母"s"結尾的字串都匹配.用RegExp()也可以定義一個等價的Regex,代碼如下:
var pattern = new RegExp("s$");
無論是用Regex直接量還是用建構函式RegExp(),建立一個RegExp對象都是比較容易的.較為困難的任務是用Regex文法來描述字元的模式.JavaScript採用的是Perl語言Regex文法的一個相當完整的子集.
Regex的模式規範是由一系列字元構成的.大多數字元(包括所有字母數字字元)描述的都是按照字面意思進行匹配的字元.這樣說來,Regex /java/就和所有包含子串 "java" 的字串相匹配.雖然Regex中的其它字元不是按照字面意思進行匹配的,但它們都具有特殊的意義.Regex /s$/ 包含兩個字元.
第一個特殊字元 "s" 是按照字面意思與自身相匹配.第二個字元 "$" 是一個特殊字元,它所匹配的是字串的結尾.所以Regex /s$/ 匹配的就是以字母 "s" 結尾
的字串.
1.直接量字元
我們已經發現了,在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匹配的則是空白符之外的任何字元.
正則表灰式的字元類
字元 匹配
____________________________________________________
[...] 位於括弧之內的任一字元
[^...] 不在括弧之中的任一字元
. 除了分行符號之外的任一字元,等價於[^\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;
Regex(regular expression)對象包含一個Regex模式(pattern)。它具有用Regex模式去匹配或代替一個串(string)中特定字元(或字元集合)的屬性(properties)和方法(methods)。要為一個單獨的Regex添加屬性,可以使用Regex建構函式(constructor function),無論何時被調用的預設定的Regex擁有靜態屬性(the predefined RegExp object has static properties that are set whenever any regular expression is used, 我不知道我翻得對不對,將原文列出,請自行翻譯)。
建立:
一個文字格式設定或Regex建構函式
文字格式設定: /pattern/flags
Regex建構函式: new RegExp("pattern"[,"flags"]);
參數說明:
pattern -- 一個Regex文本
flags -- 如果存在,將是以下值:
g: 全域匹配
i: 忽略大小寫
gi: 以上組合
[注意] 文字格式設定的參數不用引號,而在用建構函式時的參數需要引號。如:/ab+c/i new RegExp("ab+c","i")是實現一樣的功能。在建構函式中,一些特殊字元需要進行轉意(在特殊字元前加"\")。如:re = new RegExp("\\w+")
Regex中的特殊字元
字元 含意
\ 做為轉意,即通常在"\"後面的字元不按原來意義解釋,如/b/匹配字元"b",當b前面加了反斜杆後/\b/,轉意為匹配一個單詞的邊界。
-或-
對Regex功能字元的還原,如"*"匹配它前面元字元0次或多次,/a*/將匹配a,aa,aaa,加了"\"後,/a\*/將只匹配"a*"。
^ 匹配一個輸入或一行的開頭,/^a/匹配"an A",而不匹配"An a"
$ 匹配一個輸入或一行的結尾,/a$/匹配"An a",而不匹配"an A"
* 匹配前面元字元0次或多次,/ba*/將匹配b,ba,baa,baaa
+ 匹配前面元字元1次或多次,/ba*/將匹配ba,baa,baaa
? 匹配前面元字元0次或1次,/ba*/將匹配b,ba
(x) 匹配x儲存x在名為$1...$9的變數中
x|y 匹配x或y
{n} 精確匹配n次
{n,} 匹配n次以上
{n,m} 匹配n-m次
[xyz] 字元集(character set),匹配這個集合中的任一一個字元(或元字元)
[^xyz] 不匹配這個集合中的任何一個字元
[\b] 匹配一個退格符
\b 匹配一個單詞的邊界
\B 匹配一個單詞的非邊界
\cX 這兒,X是一個控制符,/\cM/匹配Ctrl-M
\d 匹配一個字數字元,/\d/ = /[0-9]/
\D 匹配一個非字數字元,/\D/ = /[^0-9]/
\n 匹配一個分行符號
\r 匹配一個斷行符號符
\s 匹配一個空白字元,包括\n,\r,\f,\t,\v等
\S 匹配一個非空白字元,等於/[^\n\f\r\t\v]/
\t 匹配一個定位字元
\v 匹配一個重直定位字元
\w 匹配一個可以組成單詞的字元(alphanumeric,這是我的意譯,含數字),包括底線,如[\w]匹配"$5.98"中的5,等於[a-zA-Z0-9]
\W 匹配一個不可以組成單詞的字元,如[\W]匹配"$5.98"中的$,等於[^a-zA-Z0-9]。
說了這麼多了,我們來看一些Regex的實際應用的例子:
E-mail地址驗證:
function test_email(strEmail) {
var myReg = /^[_a-z0-9]+@([_a-z0-9]+\.)+[a-z0-9]{2,3}$/;
if(myReg.test(strEmail)) return true;
return false;
}
HTML代碼的屏蔽
function mask_HTMLCode(strInput) {
var myReg = /<(\w+)>/;
return strInput.replace(myReg, "<$1>");
}
Regex對象的屬性及方法
預定義的Regex擁有有以下靜態屬性:input, multiline, lastMatch, lastParen, leftContext, rightContext和$1到$9。其中input和multiline可以預設定。其他屬性的值在執行過exec或test方法後被根據不同條件賦以不同的值。許多屬性同時擁有長和短(perl風格)的兩個名字,並且,這兩個名字指向同一個值。(JavaScript類比perl的Regex)
Regex對象的屬性 屬性 含義
$1...$9 如果它(們)存在,是匹配到的子串
$_ 參見input
$* 參見multiline
$& 參見lastMatch
$+ 參見lastParen
$` 參見leftContext
$' 參見rightContext
constructor 建立一個對象的一個特殊的函數原型
global 是否在整個串中匹配(bool型)
ignoreCase 匹配時是否忽略大小寫(bool型)
input 被匹配的串
lastIndex 最後一次匹配的索引
lastParen 最後一個括弧括起來的子串
leftContext 最近一次匹配以左的子串
multiline 是否進行多行匹配(bool型)
prototype 允許附加屬性給對象
rightContext 最近一次匹配以右的子串
source Regex模式
lastIndex 最後一次匹配的索引
Regex對象的方法
方法 含義
compile Regex比較
exec 執行尋找
test 進行匹配
toSource 返回特定對象的定義(literal representing),其值可用來建立一個新的對象。重載Object.toSource方法得到的。
toString 返回特定對象的串。重載Object.toString方法得到的。
valueOf 返回特定對象的原始值。重載Object.valueOf方法得到
例子
將輸出"Smith, John"