標籤:javascript Regex
Regex 是一個描述字元模式的對象,JavaScript的RegExp類表示Regex,String和RegExp都定義了方法,後者使用Regex進行強大的模式比對和文本檢索與替換功能。
JavaScript中的Regex用RegExp對象表示,可以使用RegExp()建構函式來建立RegExp對象,不過RegExp對象更多的是通過一種特殊的直接量文法來建立,Regex直接量定義為包含在一對斜線之間的字元,如下兩種用法等效,都是用來匹配所有以字母“s”結尾的字串:
var pattern = /s$/;var pattern = new RegExp(“s$”);
Regex中的所有字母和數字都是按照字面含義進行匹配的,JavaScriptRegex文法也支援非字母的字元匹配,這些字元需要通過反斜線\作為首碼進行轉義,如下所示Regex中的直接量字元(許多標點符號具有特殊含義,如^ $ . * + ? = ! : | / \ ( ) [ ] { }):
字母和數字字元:本身\o:NUL字元\t:定位字元\n:分行符號\v:垂直定位字元\f:換頁符\r:斷行符號符\xnn:由十六進位數nn指定的拉丁字元\unnnn:有十六進位數nnnn指定的Unicode字元\cX:控制字元^X
將直接量字元單獨放入方括弧內就組成了字元類,一個字元類可以匹配它所包含的任一字元,下面列出Regex的字元類:
[...]:方括弧內的任一字元,如[abc]表示a、b和c中的任意一個字元,[a-z]表示任意一個小寫字母,[a-zA-Z0-9]表示任意一個字母或者數字。[^...]:不在方括弧內的任一字元,如[^abc]表示除了a、b和c的其它任意一個字元。.:除分行符號和其他Unicode行終止符之外的任一字元\w:任何ASCII字元組成的單詞\W:任何不是ASCII字元組成的單詞`這裡寫代碼片`\s:任何Unicode空白符\S:任何非Unicode空白符的字元\d:任何ASCII數字\D:任何ASCII數字之外的任何字元[\b]:退格直接量(特例)
如果Regex中多個字元重複多次,一個一個寫起來難免顯得麻煩,Regex支援字元重複表格示的形式,文法如下:
{n, m}:匹配前一項至少n次,但不能超過m次{n, }:匹配前一項n次或者更多次{n}:匹配前一項n次?:匹配前一項0次或者1次+:匹配前一項1次或者多次*:匹配前一項0次或多次
例如:
/\d{2,4}/:匹配2~4個數字/\w{3}\d?/:精確匹配3個ASCII字元和1個可選的數字/\s+java\s+/:匹配前後帶有一個或多個空格的字串“java”/[^(]*/:匹配一個或多個非左括弧的字元
上面列出的Regex的匹配重複字元是儘可能多地匹配,而且允許後續的Regex繼續匹配,這種匹配模式為貪婪模式,當然也有非貪婪模式,即儘可能少地匹配,做法是在重複匹配字元的後面跟隨一個問號。
例如:/a+/和/a+?/對於“aaa”來說,前者貪婪匹配三個字母,後者非貪婪只匹配第一個字母。使用非貪婪的匹配模式所得到的結果可能和期望不一致,如/a+b/和/a+?b/對於“aaab”來說,它們匹配的都是整個字串,前者貪婪模式無可置疑,但後者非貪婪模式怎麼會如此呢,這是因為Regex的模式比對總是會尋找字串中第一個可能匹配的位置,由於該匹配是從字串的第一個字元開始的,因此在這裡不考慮它的子串中更短的匹配。
Regex的文法還包括指定選擇項、子運算式分組和引用前一子運算式的特殊字元,如下所示:
|:選擇,匹配的是該符號左邊的子運算式或右邊的子運算式(...):組合,將幾個項組合為一個單元,這個單元可通過“*”、“+”、“?”和“|”等符號加以修飾,而且可以記住和這個組合相匹配的字串以供此後的引用使用。(?:...):只組合,把項組合到一個單元,但不記憶與該組相匹配的字元。\n:和第n個分組第一次匹配的字元相匹配,組是圓括弧內的子運算式,也有可能是嵌套的,組索引是從左至右的左括弧數,“(?:”形式的分組不進行數字編碼。
例如:
/ab|cd|ef/:表示可以匹配字串ab,也可以匹配字串cd,還可以匹配字串ef。/\d{3}|[a-z]{4}/:表示匹配的是三位元字或者四個小寫字母。/a|ab/:對於字串“ab”,只匹配a而不是全部的ab,因為選擇項從左至右開始匹配,直到發現了匹配,如果左邊的選擇項匹配成功,就忽略右邊的匹配項,即使右邊的匹配項產生更好的匹配結果。/java(script)?/:可以匹配字串java,其後可以有script也可以沒有,使用了圓括弧分組。/(ab|cd)+|ef/:可以匹配字串ef,也可以匹配字串ab或cd的一次或多次重複。/([Jj]ava([Ss]cript)?)\sis\s(fun\w*)/:嵌套形式,其中([Ss]cript)?)可以用\2代替。/([Jj]ava(?:[Ss]cript)?)\sis\s(fun\w*)/:嵌套形式,其中(?:[Ss]cript)?)僅僅用於分組,\2引用的變成了(fun\w*)。/([‘ “])[^‘ “]*\1/:字串兩端是一對單引號或者雙引號,中間是任意個非單、雙引號的字元,如果寫成/([‘ “])[^‘ “]*[‘ “]/是不合邏輯的,因為字串兩端無法保證單、雙引號的配對。
Regex還可以指定匹配位置,如下所示:
^:匹配字串的開頭,在多行檢索時,匹配一行的開頭。$:匹配字串的結尾,在多行檢索時,匹配一行的結尾。\b:匹配一個單詞的邊界。\B:匹配非單詞邊界的位置。(?=p):零寬正向先行斷言,要求接下來的字元都與p匹配,但不能包括匹配p的那些字元,並不是真正意義上的匹配。(?!p):零寬負向先行斷言,要求接下來的字元不與p匹配。
例如:
/^JavaScript$/:匹配單詞JavaScript。/\bJava\b/:匹配單詞Java本身。/\B[Ss]cript/:與JavaScript和postscript匹配,但不與script和Scripting匹配。/[Jj]ava([Ss]cript)?(?=\:)/:可以匹配“JavaScript: The Definition Guide”中的“JavaScript”,但是不能匹配“Java in a Nutshell”中的“Java”,因為後者沒有冒號。/Java(?!Script)([A-Z]\w*)/:可以匹配Java後跟隨一個大寫字母和任意多個ASCII字元,但Java後面不能跟隨Script。
Regex還可以指定修飾符,修飾符是放在第二個“/”的後面,有三個修飾符。
i:執行不區分大小寫匹配。g:執行一個全域匹配,即找到所有的匹配,而不是在找到第一個就停止。m:多行模式比對,^匹配一行的開頭和字串的開頭,$匹配行的結尾和字串的結尾。
例如:
/java$/im:可以匹配“java”,也可以匹配“Java\nis fun”。/\bjava\b/gi:不區分大小寫匹配所有單詞“java”。
通過String使用Regex——
上面介紹了那麼多Regex的文法,那麼怎麼來使用它們呢?String對象提供了4種方法:search()、replace()、match()和split(),它們功能不同,各有特色,詳細用法可查看String對象,下面只介紹replace()的一種有趣的用法。
var quote = /``([^``]*)``/g;text.replace(quote, ‘ “$1” ‘);
上面的replace()用法中,關鍵的地方在於$1,它只是用中文半形引號’’替換英文引號“,引號之間的內容保持不變。
通過RegExp對象使用Regex——
RegExp對象的建構函式帶有兩個參數,第一個參數是Regex,也就是Regex直接常量兩個斜線之間的部分,但是要用“\”字元作為逸出字元的首碼,第二個參數是可選的修飾符,如下例子所示:
var zipcode = new RegExp(“\\d{5}”, “g”);
使用RegExp的好處之一就是可以動態建立Regex,而不必像直接常量那樣寫死在代碼中,靈活性更強。
RegExp對象包含5個屬性:source,唯讀字串,Regex文本;global,唯讀布爾值,說明Regex是否帶有修飾符g;ignoreCase,唯讀布爾值,說明Regex是否帶有修飾符i;multiline,唯讀布爾值,說明Regex是否帶有修飾符m;lastIndex,可讀可寫整數,如果匹配模式帶有g修飾符,這個屬性儲存區在整個字串中下一次檢索的開始位置。
RegExp對象包含2個方法,exec()和test()。前者類似於String.match(),參數為一個字串,匹配失敗返回null,成功匹配時返回數組,並提供關於本次匹配的完整資訊。後者則較為簡單,參數也是一個字串,如果包含Regex的一個匹配結果,則返回true。
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
JavaScriptRegex