ECMAScript經過RegExp(Regular Expression)類型來支持正則表達式。javascript
var expression= / pattern / flags ;html
pattern(模式)部分能夠是任何正則表單時。每一個正則表達式均可帶有一個或多個flags(標誌)。java
g(global全局模式) | 應用於全部字符串,而非發現第一個匹配項中止 |
i(case-insensitive) | 肯定匹配項時忽略模式與字符串的大小寫 |
m(multiline) | 在到達一行文本末尾時還會繼續查找下一行是否存在與模式匹配的項 |
舉例:正則表達式
1 /* 2 * 匹配字符串中全部「at」的實例 3 */ 4 var pattern1=/at/g; 5 /* 6 * 匹配第一個「cat」或「bat」的實例,不區分大小寫 7 */ 8 var patern2=/[cb]at/i; 9 /* 10 * 匹配全部以「at」結尾的3個字符的組合,不區分大小寫 11 */ 12 var pattern3=/.at/gi; 13 /* 14 * 匹配全部「.at」,不區分大小寫 15 */ 16 var pattern4=/\.at/gi;
正則表達式經常使用來檢索替換符合某個模式的文本,Regular Expreesion一般簡寫爲RegExp RegEx RE具體概念(http://zh.wikipedia.org/wiki/正則表達式)chrome
正則表達式學習:http://www.greenend.org.uk/rjk/tech/regexp.html(各類語言或工具軟件不一樣的正則表達式文法規定);express
http://deerchao.net/tutorials/regex/regex.htm(正則表達式30min入門);數組
http://mengzhuo.org/regex/(一個在線正則表達式驗證器)。瀏覽器
讓咱們看看這下面這個例子:函數
1 /* 2 * 匹配第一個"bat"或「cat」,不區分大小寫 3 */ 4 var pattern1=/[bc]at/i; 5 /* 6 * 和pattern1相同,只不過是用來了構造函數建立 7 */ 8 var pattern2=new RegExp("[bc]at","i");
這兩個正則表達式是徹底等價的,可是值得注意的是傳遞給構造函數RegExp的兩個參數都是字符串類型,因此,在某些狀況下,會對字符串參數進行雙重轉義。即對元字符進行轉義,轉義後的元字符再進行轉義。工具
牢記元字符(metacharacters):( [ { \ ^ $ | ? * + . } ] ) 14個很是重要的元字符
舉例:
想要匹配字符串 | 字面量模式 | 等價的字符串 |
"bat"或"cat" | /[bc]at/ | "[bc]at" |
".at" | /\.at/ | "\\.at" |
"\hello\world\" | \\hello\\world\\ | "\\\\hello\\\\world\\\\" |
使用正則表達式字面量和使用RegExp構造函數建立的正則表達式還有一點也是有區別的,那就是在ECMAScript3中,使用正則表達式字面量始終會事會使用同一個RegExp實例,而RegExp構造函數會從新建立一個新的實例。但在ECMAScript5中明確規定,適應正則表達式字面量必須和直接調用RegExp構造函數同樣,每次都建立一個新的RegExp實例。IE9+,Firefox4+,和chrome都據此作出了修改。
請看下面的例子(運行標準爲ECMAScript3):
1 var re=null, 2 i; 3 for (i = 0; i < 10; i++) { 4 re=/cat/g 5 document.write(re.test("catastrophe")); 6 } 7 for (i = 0; i < 10; i++) { 8 re = new RegExp("cat", "g"); 9 document.write(re.test("catastrophe")); 10 };
第一個for循環當re第二次調用時,會是從索引3進行查找。因此之後的都會顯示false.而在chrome中運行則沒有問題,在作這個例子的時候,由於一個小的問題,致使浪費了不少的時間,原本很快就能夠解決的,是我打了一箇中文輸入法的括弧。
RegExp的屬性:這些東西沒有多大的用處,由於這些所有都包括在模式聲明中了:
global,ignoreCase,lastIndex,multiline,source(RegExp並非以字符串返回的,而是經過專注的字面量)
1 var pattern1=/\[bc\]at/i; 2 document.write(pattern1.global); //false 3 document.write(pattern1.ignoreCase); //true 4 document.write(pattern1.lastIndex); //0 5 document.write(pattern1.multiline); //false 6 document.write(pattern1.source); //"\[bc\]at" 7 var pattern2= new RegExp("\\[bc\\]at","i"); 8 9 document.write(pattern2.global); //false 10 document.write(pattern2.ignoreCase); //true 11 document.write(pattern2.lastIndex); //0 12 document.write(pattern2.multiline); //false 13 document.write(pattern2.source); //"\[bc\]at"
RegExp對象方法:
RegExp對象的主要方法是exec(),該方法是專門爲捕獲組而設計的。exec()接受一個參數,就是要應用模式的文本,而後返回包含第一個匹配項信息的數組。或者在沒有匹配項的狀況下返回null.返回的數組有額外的兩個屬性:index和input.其中index表示匹配項在文本中的位置,而input表示應用正則表達式的字符串。
1 var text="mom and dad and baby"; 2 var pattern= /mom( and dad( and baby)?)?/gi; 3 4 var matches= pattern.exec(text); 5 document.write(matches.index+"<br/>"); //0 6 document.write(matches.input+"<br/>"); //mom and dad and baby 7 document.write(matches[0]+"<br/>"); //mom and dad and babt 8 document.write(matches[1]+"<br/>"); //and dad and baby 9 document.write(matches[2]+"<br/>"); //and baby
當文本傳入exec()方法後,發現了第一個匹配項,因此index屬性爲0,由於匹配項和文本相同。第二個匹配項是and dad and baby ,第三個匹配項是and baby.在調用非全局exec()方法時,,返回的數組與調用方法 String.match() 返回的數組是相同的。可是,在調用全局exec()全局方法時,exec的方法稍顯複雜,他會在RegExp對象的lastIndex屬性指定的字符處開始檢索字符串,在exec()方法找到匹配文本後,以匹配文本的最後一個字符的下一個位置設置爲RegExp的lastIndex屬性,這就是說當用exec()方法遍歷整個文本後,找不到匹配項後,它會返回null,而且把lastIndex設置爲0。
看下面的例子:
1 var pattern=/.at/g; 2 var matches = pattern.exec(text); 3 document.write(matches.index); //0 4 document.write(matches[0]); //sat 5 document.write(pattern.lastIndex); //3
在IE中,JavaScript實如今lastIndex會出現差別,即便在非全局模式下,lastIndex屬性也會發現變化。
正則表達式的第二個方法是test(),它接受應給字符串參數,在模式與該參數匹配的狀況下返回true,反之返回false。
RegExp對象繼承的toLocaleString()和toString()方法都會返回正則表達式的字面量,與建立正則表達式的方式無關。而是用valueOf()方法則返回正則表達式自己。
例如:
1 var pattern = new RegExp("\\[bc\\]at", "gi"); 2 document.write(pattern.toString()); //"/\[bc\]at/gi" 3 document.write(pattern.toLocaleString());//"/\[bc\]at/gi" 4 document.write(pattern.valueOf()); //"/\[bc\]at/gi"
RegExp構造函數的屬性:有些瀏覽器並不支持某些屬性,好比Opera和IE
長屬性名 | 短屬性名 | 說明 |
input | $_ | 最近一次要匹配的字符串。 |
lastMatch | $& | 最近一次的匹配項 |
lastParen | $+ | 最近一次匹配的捕獲組 |
leftContent | $` | input字符串中lastMatch以前的文本 |
multiline | $* | 布爾值,表示是否全部表達式都使用多行模式 |
rightContext | $' | Input字符串中lastMatch以後的文本 |
請看下面的例子:
1 var text="this has been a short summer"; 2 var pattern=/(.)hort/g; 3 4 if(pattern.test(text)){ 5 alert(RegExp.input); //this has been a short summer 6 alert(RegExp.leftContext); //this has been a 7 alert(RegExp.rightContext); //summer 8 alert(RegExp.lastMatch); //short 9 alert(RegExp.lastParen); //s 10 alert(RegExp.multiline); //false 11 }
利用短屬性名,由於這些短屬性名不是有效的ECMAScript標識符,所以用方括號包括起來:
請看下面的例子,與上面的例子有相同的效果:
1 var text="this has been a short summer"; 2 var pattern=/(.)hort/g; 3 4 if(pattern.test(text)){ 5 alert(RegExp.$_); //this has been a short summer 6 alert(RegExp["$`"]); //this has been a 7 alert(RegExp["$'"]); //summer 8 alert(RegExp["$&"]); //short 9 alert(RegExp["$+"]); //s 10 alert(RegExp["$*"]); //false 11 }
除了上述的幾個屬性外,還有多達9個用於存儲捕獲組的構造函數屬性。訪問這些屬性的方法是RegExp.$1,RegExp$2~RegExp.$9,分別用於存儲第一,第二到第九個捕獲組。
1 var text="this has been a short summer"; 2 var pattern=/(..)or(.)/g; 3 4 if(pattern.test(text)){ 5 alert(RegExp.$1); //sh 6 alert(RegExp.$2); //t 7 }
這個正則表達式的意思是檢索長度爲5的字符串,其中倒數第3,2位爲or,這個正則表達式有兩個捕獲組,圓括弧裏面的,分別是(..)和(.)
關於捕獲組的文章:http://blog.csdn.net/lxcnn/article/details/4146148
關於ECMAScript中正則表達式的侷限性(下列是不支持的特性):請訪問http://www.regular-expressions.info/javascript.html
匹配字符串開始和結尾的\A和\Z錨;
向後查找(lookbehind);
並集和交集類;
原子組(atomic grouping);
Unicode支持(單個字符除外,如\uFFFF);
命名的捕獲組;
s(single,單行)和x(free-spading,無間隔)匹配模式;
條件匹配;
正則表達式註釋;
總而言之,ECMAScript正則表達式仍然是十分強大。