網上正則表達式的教程夠多了,但因爲javascript的歷史比較悠久,也比較古老,所以有許多特性是不支持的。咱們先從最簡單地提及,文章所演示的正則基本都是perl方式。javascript
元字符
( [ { \ ^ $ | ) ? * + .html
預約義的特殊字符
字符 |
正則 |
描述 |
\t |
/\t/ |
製表符 |
\n |
/\n/ |
製表符 |
\r |
/\r/ |
回車符 |
\f |
/\f/ |
換頁符 |
\a |
/\a/ |
alert字符 |
\e |
/\e/ |
escape字符 |
\cX |
/\cX/ |
與X相對應的控制字符 |
\b |
/\b/ |
與回退字符 |
\v |
/\v/ |
垂直製表符 |
\0 |
/\0/ |
空字符 |
字符類
簡單類前端
原則上正則的一個字符對應一個字符,咱們能夠用[]把它們括起來,讓[]這個總體對應一個字符。如java
alert(/ruby/.test( "ruby" )); //true |
alert(/[abc]/.test( "a" )); //true |
alert(/[abc]/.test( "b" )); //true |
alert(/[abc]/.test( "c" )); //true |
alert( "a bat ,a Cat,a fAt bat ,a faT cat" .match(/[bcf]at/gi)); //bat,Cat,fAt,bat,faT,cat |
負向類正則表達式
也是在那個括號裏作文章,前面加個元字符進行取反,表示匹配不能爲括號裏面的字符。api
alert(/[^abc]/.test( "a" )); //false |
alert(/[^abc]/.test( "b" )); //false |
alert(/[^abc]/.test( "6" )); //true |
alert(/[^abc]/.test( "gg" )); //true |
範圍類瀏覽器
仍是在那個中括號裏面作文章。有時匹配的東西過多,並且類型又相同,所有輸入太麻煩,咱們能夠用它。特徵就是在中間加了個橫線。ruby
組合類this
仍是在那個中括號裏面作文章。容許用中括號匹配不一樣類型的單個字符。spa
alert(/[a-f]/.test( "b" )); //true |
alert(/[a-f]/.test( "k" )); //false |
alert(/[a-z]/.test( "h" )); //true |
alert(/[A-Z]/.test( "gg" )); //false |
alert(/[^H-Y]/.test( "G" )); //true |
alert(/[0-9]/.test( "8" )); //true |
alert(/[^7-9]/.test( "6" )); //true |
alert(/[a-m1-5\n]/.test( "a" )) //true |
alert(/[a-m1-5\n]/.test( "3" )) //true |
alert(/[a-m1-5\n]/.test(a)) //true |
alert(/[a-m1-5\n]/.test( "r" )) //false |
預約義類
仍是在那個中括號裏面作文章,不過它好像已經走到盡頭了。因爲是中括號的馬甲,所以它們仍是對應一個字符。
字符 |
等同於 |
描述 |
. |
[^\n\r] |
除了換行和回車以外的任意字符 |
\d |
[0-9] |
數字字符 |
\D |
[^0-9] |
非數字字符 |
\s |
[ \t\n\x0B\f\r] |
空白字符 |
\S |
[^ \t\n\x0B\f\r] |
非空白字符 |
\w |
[a-zA-Z_0-9] |
單詞字符(全部的字母) |
\W |
[^a-zA-Z_0-9] |
非單詞字符 |
alert(/\d/.test( "3" )) //true |
alert(/\d/.test( "w" )) //false |
alert(/\D/.test( "w" )) //true |
alert(/\w/.test( "w" )) //true |
alert(/\w/.test( "司" )) //false |
alert(/\W/.test( "徒" )) //true |
alert(/\s/.test( " " )) //true |
alert(/\S/.test( " " )) //false |
alert(/\S/.test( "正" )) //true |
alert(/./.test( "美" )) //true |
alert(/./.test( " " )) //true |
量詞
因爲元字符與特殊字符或字符類或者它們的組合(中括號)甚至它們的馬甲(預約義類)都是一對一進行匹配。咱們要匹配「司徒正美這個詞」,最簡單都要/..../,若是長到50多個字符豈不是要死人。所以咱們逼切須要一個簡單的操做,來處理這數量關係。
簡單量詞
代碼 |
類型 |
描述 |
? |
軟性量詞 |
出現零次或一次 |
* |
軟性量詞 |
出現零次或屢次(任意次) |
+ |
軟性量詞 |
出現一次或屢次(至道一次) |
{n} |
硬性量詞 |
對應零次或者n次 |
{n,m} |
軟性量詞 |
至少出現n次但不超過m次 |
{n,} |
軟性量詞 |
至少出現n次(+的升級版) |
alert(/..../.test( "司徒正美" )) //true |
alert(/司徒正美/.test( "司徒正美" )) //true |
alert(/[\u4e00-\u9fa5]{4}/.test( "司徒正美" )) //true |
alert(/[\u4e00-\u9fa5]{4}/.test( "司徒正美55" )) //true |
alert(/^[\u4e00-\u9fa5]+$/.test( "正則表達式" )) //true |
alert(/^[\u4e00-\u9fa5]+$/.test( "正則表達式&*@@" )) //false |
alert(/\d{6}/.test( "123456" )) //true |
alert(/[ruby]{2}/.test( "rr" )) //true |
alert(/[ruby]{2}/.test( "ru" )) //true |
alert(/[ruby]{2}/.test( "ry" )) //true |
/[\u4e00-\u9fa5]/用於匹配單個漢字。
貪婪量詞,惰性量詞與支配性量詞
貪婪量詞,上面提到的全部簡單量詞。就像成語中說的巴蛇吞象那樣,一口吞下整個字符串,發現吞不下(匹配不了),再從後面一點點吐出來(去掉最後一個字符,再看這時這個整個字符串是否匹配,不斷這樣重複直到長度爲零)
隋性量詞,在簡單量詞後加問號。因爲太懶了,先吃了前面第一個字符,若是不飽再捏起多添加一個(發現不匹配,就讀下第二個,與最初的組成一個有兩個字符串的字符串再嘗試匹配,若是再不匹配,再吃一個組成擁有三個字符的字符串……)。其工做方式與貪婪量詞相反。
支配性量詞,在簡單量詞後加加號。上面兩種都有個不斷嘗試的過程,而支配性量詞卻只嘗試一次,不合口味就算了。就像一個出身高貴居支配地位的公主。但你也能夠說它是最懶量詞。因爲javascript不支持,因此它連出場的機會也沒有了。
// var re3 = /.*+bbb/g;//支配性,javascript不支持,IE與全部最新的標準瀏覽器都報錯 |
alert(re1.test( "abbbaabbbaaabbbb1234" )+ "" ); //true |
alert(re1.exec( "abbbaabbbaaabbbb1234" )+ "" ); //null |
alert( "abbbaabbbaaabbbb1234" .match(re1)+ "" ); //abbbaabbbaaabbbb |
alert(re2.test( "abbbaabbbaaabbbb1234" )+ "" ); //true |
alert(re2.exec( "abbbaabbbaaabbbb1234" )+ "" ); //aabbb |
alert( "abbbaabbbaaabbbb1234" .match(re2)+ "" ); //abbb,aabbb,aaabbb |
分組
到目前爲止,咱們只能一個字符到匹配,雖然量詞的出現,能幫助咱們處理一排密緊密相連的同類型字符。但這是不夠的,下面該輪到小括號出場了,中括號表示範圍內選擇,大括號表示重複次數。小括號容許咱們重複多個字符。
alert(/(dog){2}/.test( "dogdog" )) //true |
alert( "baddad" .match(/([bd]ad?)*/)) //baddad,dad |
alert( "mon and dad" .match(/(mon( and dad)?)/)) //mon and dad,mon and dad, and dad |
反向引用
反向引用標識由正則表達式中的匹配組捕獲的子字符串。每一個反向引用都由一個編號或名稱來標識,並經過「\編號」表示法進行引用。
alert(RegExp.$1); //990000 |
alert(/(dog)\1/.test( "dogdog" )) //true |
var newNum = num.replace(/(\d{4}) (\d{4})/, "$2 $1" ); |
候選
繼續在分組上作文章。在分組中插入管道符(「|」),把它劃分爲兩個或多個候多項。
var reg = /(red|black|yellow)!!/; |
alert(reg.test( "red!!" )) //true |
alert(reg.test( "black!!" )) //true |
alert(reg.test( "yellow!!" )) //true |
非捕獲性分組
並非全部分組都能建立反向引用,有一種特別的分組稱之爲非捕獲性分組,它是不會建立反向引用。反之,就是捕獲性分組。要建立一個非捕獲性分組,只要在分組的左括號的後面緊跟一個問號與冒號就好了。
題目,移除全部標籤,只留下innerText!
var text = html.replace(/<(?:.|\s)*?>/g, "" ); |
注意:javascript不存在命名分組
前瞻
繼續在分組內作文章。前瞻與後瞻其實都屬於零寬斷言,但javascript不支持後瞻。
零寬斷言 |
正則 |
名稱 |
描述 |
(?=exp) |
正向前瞻 |
匹配exp前面的位置 |
(?!exp) |
負向前瞻 |
匹配後面不是exp的位置 |
(?<=exp) |
正向後瞻 |
匹配exp後面的位置不支持 |
(?<!exp) |
負向後瞻 |
匹配前面不是exp的位置不支持 |
正向前瞻用來檢查接下來的出現的是否是某個特定的字符集。而負向前瞻則是檢查接下來的不該該出現的特定字符串集。零寬斷言是不會被捕獲的。
var reBed = /(bed(?=room)) ///在咱們捕獲bed這個字符串時,搶先去看接下來的字符串是否是room |
alert(reBed.test(str1)); //true |
alert(RegExp.$2 === "" ) //true |
alert(reBed.test(str2)) //false |
var reBed = /(bed(?!room))/ //要來它後面不能是room |
alert(reBed.test(str1)) //false |
alert(reBed.test(str2)) //true |
題目,移除hr之外的全部標籤,只留下innerText!
var text = html.replace(/<(?!hr)(?:.|\s)*?>/ig, "" ) |
alert(text) //Ruby Louvre<hr/>by 司徒正美 |
邊界
一個要與字符類合用的東西。
邊界 |
正則 |
名稱 |
描述 |
^ |
開頭 |
注意不能緊跟於左中括號的後面 |
$ |
結尾 |
|
\b |
單詞邊界 |
指[a-zA-Z_0-9]以外的字符 |
\B |
非單詞邊界 |
|
題目,設計一個字符串原型方法,實現首字母大寫!
String.prototype.capitalize = function () { |
return this .replace(/^\w/, function (s) { |
alert(a.capitalize()) //Ruby |
單詞邊界舉例。要匹配的東西的前端或未端不能爲英文字母阿拉伯字數字或下橫線。
var str = "12w-eefd&efrew" ; |
alert(str.match(/\b\w+\b/g)) //12w,eefd,efrew |
實例屬性 |
描述 |
global |
是當前表達式模式首次匹配內容的開始位置,從0開始計數。其初始值爲-1,每次成功匹配時,index屬性都會隨之改變。 |
ignoreCase |
返回建立RegExp對象實例時指定的ignoreCase標誌(i)的狀態。若是建立RegExp對象實例時設置了i標誌,該屬性返回True,不然返回False,默認值爲False。 |
lastIndex |
是當前表達式模式首次匹配內容中最後一個字符的下一個位置,從0開始計數,常被做爲繼續搜索時的起始位置,初始值爲-1, 表示從起始位置開始搜索,每次成功匹配時,lastIndex屬性值都會隨之改變。(只有使用exec()或test()方法纔會填入,不然爲0) |
multiLine |
返回建立RegExp對象實例時指定的multiLine標誌(m)的狀態。若是建立RegExp對象實例時設置了m標誌,該屬性返回True,不然返回False,默認值爲False。 |
source |
返回建立RegExp對象實例時指定的表達式文本字符串。 |