正規表示式又叫規則表示式,一般用來檢查字串中是否有與規則相匹配的子串,達到可以對匹配的子串進行提取、刪除、替換等操作的目的。先了解有哪些方法可以使用正則對字串來實現這些操作:
RegExpObject.test(string):
檢查字串 string 中是否有與 RegExpObject 匹配。有則返回 true,否則返回 false。
RegExpObject.exec(string):
檢索字串 string 中與 RegExpObject 匹配的值。有則返回相關結果的陣列,否則返回 null。
stringObject.search(regexp):
找到字串 stringObject 中第一個與 regexp 相匹配的子串的位置。
stringObject.match(regexp):
檢索字串 stringObject 中與 regexp 匹配的值;
如果 regexp 沒有標誌 g,進行非全域性檢索,執行結果與RegExpObject.exec方法相同;
如果 regexp 有標誌 g,進行全域性檢索,返回 stringObject 中所有匹配的子字串的陣列。
stringObject.replace(regexp,replacement):
在 stringObject 找到與 regexp 匹配的子串,用 replacement 替換,返回新的字串。
stringObject.split(separator,howmany):
用 separator 為邊界,把 stringObject 分成陣列,陣列長度不能大於 howmany。
正規表示式最簡單的規則就是匹配完全相同的普通字元,比如在一個字串中,需要把一些敏感詞用*號代替。宣告字串如下:
var str = '這是1個字串,包含了我X和垃圾這2個敏感詞,而且還是垃圾這個詞還有2個,字串中還包含數字345。';
宣告一個簡單的正則直接量,然後在上面字串中匹配到符合規則的子串進行替換:
var reg = /垃圾/; var sResult = str.replace(reg,'**'); //輸出結果 console.log(sResult);
輸出的結果如圖所示:
可以看到第一個 “垃圾” 子字串被替換成**,而第二個卻沒有被替換。這是因為在宣告正則的時候,只宣告瞭匹配模式(匹配規則),預設只會檢索到第一個匹配的子字串。
有時候還需要給正規表示式新增修飾符,修飾符可以修改檢索時匹配的執行方法,正規表示式的修飾符如下:
i - 匹配時不區分大小寫
g - 全域性匹配,不會在匹配到第一個之後就中止
m - 多行匹配
在剛才的正規表示式上加上修飾符 g ,就可以進行全域性匹配,找到字串中所以符合規則的子字串進行替換,如下所示:
var str = '這是1個字串,包含了我X和垃圾這2個敏感詞,而且還是垃圾這個詞還有2個,字串中還包含數字345。'; var reg = /垃圾/g; var sResult = str.replace(reg,'**'); //輸出結果 console.log(sResult);
效果符合預期,字串中的敏感詞 “垃圾” 都被修改成了 * 號。非常容易,對吧?稍微加點難度,按照字串上的描述,還有一個敏感詞 “我X” 也需要被替換。只需要把正則改一改,使用正則的分枝條件 | 把不同的匹配分隔開,有點類似於 || 運算子。如下所示:
var str = '這是1個字串,包含了我X和垃圾這2個敏感詞,而且還是垃圾這個詞還有2個,字串中還包含數字345。'; var reg = /垃圾|我X/g; var sResult = str.replace(reg,'**'); //輸出結果 console.log(sResult);
好了,看到這裡正則也算入門了,至少會用了。但如果想用於工作,肯定是遠遠不夠的,在工作中不可能只匹配完全一樣的字元。
要匹配各種不同的字元,就需要用到元字元(正規表示式規定的一種特殊程式碼)。正規表示式的元字元很多網站都列出了詳細的表格,我在這裡就偷點懶,不一一列出,繼續說正則的例項,用到哪個再詳細解釋。
工作中有時候會拿到一些資料裡面有很多空格,來學一個使用正則刪除這些空格的小例子,如下所示:
var str = "有時候 我們拿到的 一些資料裡面 , 會一有些多 餘的空格,我 們一般都需要刪除這些 空格。 " var reg = /\s/g; var sResult= str.replace(reg,''); //輸出結果 console.log(sResult);
完美,字串中所有的空格都刪除了,不管是一個還是多個。通過上面的例項,就可以知道元字元 \s 可以匹配任意的空白符。再加上修飾符 g,所以就匹配到了字串中所有的空格。
跟著我使用例項一個一個做,學起來會非常輕鬆。再來看一個工作中經常會碰到的例子,需要把字串中所有的英文字母都刪除。正規表示式中沒有單獨表示英文的元字元,這時候需要用到 [ ] 來表示字符集合,比如 [az] 就可以匹配到 a 和 z 這兩個字母。但26個字母都寫 [ ] 在裡面好像有點多,所以可以用 [a-z] 這樣的省寫表示所有英文字母。程式碼如下所示:
var str = '有時候We我們拿到的Some一些資料裡面, 會是中文Chinese和英文English在一起,需要刪除這些英文。' var reg = /[a-z]/g; var sResult = str.replace(reg,''); //輸出結果 console.log(sResult);
結果有點不符合預期,只刪除了小寫字母,大寫字母還是紋絲不動。可以在這裡再學兩個知識點,一是在字符集合中把大寫字母也加上,比如: /[a-zA-Z]/g ;二是多加一個修飾符 i ,可以不區分大小寫,比如: /[a-z]/gi 。我就不演示了,讀者可以自己試下。
把需求反過來,把所有中文給刪除掉。可以在字符集合使用unicode編碼的中文編碼開始和結束這兩個值來匹配中文,比如: /[\u4e00-\u9fa5]/g。程式碼如下所示:
var str = '有時候We我們拿到的Some一些資料裡面, 會是中文Chinese和英文English在一起,需要刪除這些中文。' var reg = /[\u4e00-\u9fa5]/g; var sResult = str.replace(reg,''); //輸出結果 console.log(sResult);
再來看一個替換數字的例項,這次把字串中的每組數字都替換成 -- 符號,代表數字的元字元是 \d ,程式碼如下所示:
var str = '這些中文123中間,夾雜456著一些789數字,我們1010現在要做的就是把2324這些數字都換成符號'; var reg = /\d/g var sResult = str.replace(reg,'--'); //輸出結果 console.log(sResult);
看到結果,又和預期有點不一樣。現在是每個數字都換成了 -- 符號,而要求是每組數字替換成 -- 符號。所以再學一個新的知識點:限定符(又叫量詞)。限定符規定了匹配的重複方式,常用限定符如下所示:
字元 | 說明 |
---|---|
* | 重複零次或更多次 |
+ | 重複一次或更多次 |
? | 重複零次或一次 |
{n} | 重複n次 |
{n,} | 重複n次或更多次 |
{n,m} | 重複n到m次 |
學會限定符後,把上一個例子改一改。現在要替換的一組數字且並不知道它的長度,所以加上一個限定符 + (重複一次或更多次)。如下所示:
var str = '這些中文123中間,夾雜456著一些789數字,我們1010現在要做的就是把2324這些數字都換成符號'; var reg = /\d+/g var sResult = str.replace(reg,'--'); //輸出結果 console.log(sResult);
很好,符合需求,完美完成。
有時候要匹配的字元就是元字元,比如剛才用到的 +,在一個字串中需要把限定符 + 換成中文 和 字。這時候需要用到字元轉義,所謂字元轉義就是在元字元前加 \ 來取消這些字元的特殊意義。程式碼如下:
var str = '這裡有一個字串,有正+反,高+矮,大+小這些反義詞,中間的符號需要修改。'; var reg = /\+/g; var sResult = str.replace(reg,'和'); //輸出結果 console.log(sResult);
再來寫一個匹配日期的正規表示式,2020-10-10和2020/2/2都是正確的日期格式。作為初學者,寫正則的時候可以先進行分解。比如:
2020-10-10 分解成 “4個數字1個槓1或2個數字1個槓1或2個數字”,即為 /\d{4}-\d{1,2}-\d{1,2}/
2020/2/2 分解成 “4個數字1個斜槓1或2個數字1個斜槓1或2個數字”,即為 /\d{4}\/\d{1,2}\/\d{1,2}/
這時候出現了兩個分支的情況,為了看得更清楚,可以把兩個分支都用圓括號 () 括起來,如:/(\d{4}-\d{1,2}-\d{1,2})|(\d{4}\/\d{1,2}\/\d{1,2})/
var str = '2020-10-10是一個日期格式'; var str2 = '2020/2/2也是一個日期格式'; var reg = /(\d{4}-\d{1,2}-\d{1,2})|(\d{4}\/\d{1,2}\/\d{1,2})/; //輸出結果都是true console.log(reg.test(str)); console.log(reg.test(str2));
這裡的圓括號 () 在正規表示式裡面起到一個分組的作用。
看到這裡,讀者已經知道了正規表示式的普通字元、元字元、分枝條件、字符集合、限定符、字元轉義和分組這些知識,是時候做一些真正的例項了。
例項1:修改文字框內容時驗證金額
來做一個修改文字框內容時驗證金額功能,要求格式為數字;保留兩位小數點。
具體實現步驟我就不在這裡過多描述,可以參考我的另一篇文章 《原生js製作表單驗證,基本的表單驗證方法》 學習表單驗證功能如何製作。本文還是以正規表示式的規則為主要描述內容。
分析本例項的規則也是非常簡單,只有三個要求,一是必須是數字;二是必須有小數點;三是小數點後保留兩位數字。要求分析完的規則,完成正則如下:
/^\d+\\.\d{2}$/
在這個正規表示式中,要新學兩個元字元 ^ 和 $ 。
^ 匹配字串的開始位置,$ 匹配字串的結尾位置。
^\d 的意思就是必須數字開頭;+ 是限定符表示重複一次或多次; \\. 表示小數點,因為小數點本身就是元字元,所以前面要多加一個反斜槓;\d{2}$ 表示結尾必須是兩個數字。
這樣分析完,如果還不清楚的話,可以動手完成以下程式碼自己看下實際效果:
<div class="form_Box"> <dl> <dt>金額:</dt> <dd><input type="text" id="verifyMoney"><span></span></dd> </dl> </div> <script> //獲取input元素 var eInput = document.getElementById('verifyMoney'); //在input元素上繫結change事件 eInput.addEventListener('change',function(event){ //獲取輸入值 var sValue = this.value; //宣告正規表示式 var reg = /^\d+\.\d{2}$/; //獲取父級元素 var eParent = this.parentElement; //獲取input元素後的span元素,用於存放提示資訊 eSpan = eParent.getElementsByTagName('span')[0]; if(reg.test(sValue)){ //span元素上清除提示 eSpan.innerHTML = ''; }else{ //span元素上顯示提示 eSpan.innerHTML = '請輸入正確的金額格式,保留兩位小數點'; } }); </script>
例項2:文字框只能輸入數字和小數點
本例項模擬一個價格輸入框,只能輸入數字和小數點。可以通過正規表示式找到非數字和小數點的內容替換為空字串來實現。
分析本例項的規則:一是非數字;二是非小數點。正規表示式如下:
/[^\d\\.]/g
在這個表示式中,又看到一個新的知識點:^ 字元在表示式最前面表示匹配字串的開始位置,而在方括號中,表示匹配非字符集 [ ] 中的字元。所以正規表示式 /[^\d\.]/g 將匹配所有非數字和小數點的字元。
可以用此正規表示式找到文字框中匹配的字元替換為空字串,看起來就像只能輸入數字和小數點。具體實現程式碼如下:
<div class="form_Box"> <dl> <dt>金額:</dt> <dd><input type="text" id="verifyMoney"></dd> </dl> </div> <script> //獲取input元素 var eInput = document.getElementById('verifyMoney'); //在input元素上繫結input事件 eInput.addEventListener('input',function(event){ //獲取輸入值 var sValue = this.value; //宣告正規表示式 var reg = /[^\d\.]/g; this.value = sValue.replace(reg,''); }); </script>
筆者在這裡再貢獻一個嚴格的金額正規表示式,如下所示:
/^0|^\.|[^\d\.]|(?<=\.\d*)\.|(?<=\.\d{2})\d/g;
此表示式嚴格限制輸入金額的格式,只能輸入數字;不能0開頭且後面不是小數點;小數點後最多隻能有兩位數字;只能有一個小數點;不能小數點開頭。可惜有些瀏覽器不識別,其中還有未提及的知識點,有興趣的讀者可以自己嘗試分解。
例項3:身份證號碼驗證
網頁中經常會碰到需要填寫身份證號碼,提交的時候就應該先驗證身份證格式是否正確。看一下身份證號碼的編排規則:1-6位數字代表省市區,第一個數字不能是0;7-14位數字表示出生年月日;15-16位數字表示所在地的派出所程式碼;17位數字表示性別;18位數字是校檢碼,可以是0-9,也可以是字母X。根據身份證格式寫出正規表示式如下:
/^[1-9]\d{5}[12]\d{3}((0[1-9])|(1[0-2]))(([0|1|2][1-9])|3[0-1])\d{3}([0-9]|X)$/;
再來分解表示式:
- ^[1-9]\d{5} 表示省市區6個數字,第一個數字不能是0;
- [12]\d{3} 表示出生年份4位數字,限定1000-2999年;
- ((0[1-9])|(1[0-2])) 表示出生月份,限定 01 - 12 之間;
- (([0|1|2][1-9])|3[0-1]) 表示出生日期,限定 01 - 31 之間;
- \d{3}([0-9]|X)$ 表示最後4位,最後一位可以是數字或X。
具體實現程式碼如下:
<div class="form_Box"> <dl> <dt>身份證:</dt> <dd><input type="text" id="verifyCard"><span></span></dd> </dl> </div> <script> //獲取input元素 var eInput = document.getElementById('verifyCard'); //在input元素上繫結change事件 eInput.addEventListener('change',function(event){ //獲取輸入值 var sValue = this.value; //宣告正規表示式 var reg = /^[1-9]\d{5}[12]\d{3}((0[1-9])|(1[0-2]))(([0|1|2][1-9])|3[0-1])\d{3}([0-9]|X)$/; //獲取父級元素 var eParent = this.parentElement; //獲取input元素後的span元素,用於存放提示資訊 eSpan = eParent.getElementsByTagName('span')[0]; if(reg.test(sValue)){ //span元素上清除提示 eSpan.innerHTML = ''; }else{ //span元素上顯示提示 eSpan.innerHTML = '請輸入正確的身份證號碼'; } }); </script>
例項4:手機號碼驗證
來完成一個手機號碼輸入框的驗證。手機號碼必須都是數字;限制前3個數字符合手機運營商規則;總長度固定是11個數字。正規表示式如下:
/^(13[0-9]|14[5-8]|15[^4]|16[56]|17[0-9]|18[0-9]|19[189])\d{8}$/
分解表示式:
- ^() 表示括號中的分組開頭,限制前3個數字符合手機運營商規則;
1.1 13[0-9] 表示130-139開頭是正確號碼;
1.2 14[5-8] 表示145-148開頭是正確號碼;
……
1.7 19[189] 表示191,198,199開頭是正確號碼。 - \d{8}$ 表示是8個任意數字結尾。
具體實現程式碼如下:
<div class="form_Box"> <dl> <dt>手機:</dt> <dd><input type="text" id="verifyPhone"><span></span></dd> </dl> </div> <script> //獲取input元素 var eInput = document.getElementById('verifyPhone'); //在input元素上繫結change事件 eInput.addEventListener('change',function(event){ //獲取輸入值 var sValue = this.value; //宣告正規表示式 var reg = /^(13[0-9]|14[5-8]|15[^4]|16[56]|17[0-9]|18[0-9]|19[189])\d{8}$/; //獲取父級元素 var eParent = this.parentElement; //獲取input元素後的span元素,用於存放提示資訊 eSpan = eParent.getElementsByTagName('span')[0]; if(reg.test(sValue)){ //span元素上清除提示 eSpan.innerHTML = ''; }else{ //span元素上顯示提示 eSpan.innerHTML = '請輸入正確的手機號碼'; } }); </script>
例項5:電話號碼驗證
電話號碼的要求會比手機多一些,先整理目前電話號碼相關規則:
區號0開頭,共3-4個數字;區號可能會用圓括號括起來;區號後面可能直接連線號碼,也可能與號碼之間有 空格 或 - ;號碼是7-8個數字。根據規則寫出正規表示式如下:
/^((0\d{2,3})|(\\ (\d{3,4}\\)))[-\s]?([2-9]\d{6,7})$/
分解表示式:
- 分枝 ^((0\d{2,3}) 表示區號是3-4個數字,如 020;
- 分枝 (\ (\d{3,4}\))) 表示用圓括號包含區號,如(020);
- [-\s]? 表示區號後面可以直接連線號碼,也可以有一個空格或一個 - ;
- ([2-9]\d{6,7})$ 表示電話號碼,不能是0和1開頭的7位或8位數字。
具體實現程式碼如下:
<div class="form_Box"> <dl> <dt>電話:</dt> <dd><input type="text" id="verifyTel"><span></span></dd> </dl> </div> <script> //獲取input元素 var eInput = document.getElementById('verifyTel'); //在input元素上繫結change事件 eInput.addEventListener('change',function(event){ //獲取輸入值 var sValue = this.value; //宣告正規表示式 var reg = /^((0\d{2,3})|(\(\d{3,4}\)))[-\s]?([2-9]\d{6,7})$/; //獲取父級元素 var eParent = this.parentElement; //獲取input元素後的span元素,用於存放提示資訊 eSpan = eParent.getElementsByTagName('span')[0]; if(reg.test(sValue)){ //span元素上清除提示 eSpan.innerHTML = ''; }else{ //span元素上顯示提示 eSpan.innerHTML = '請輸入正確的電話號碼'; } }); </script>
如果要同時驗證手機和電話號碼,正規表示式如下:
/(^(13[0-9]|14[5-8]|15[^4]|16[56]|17[0-9]|18[0-9]|19[189])\d{8}$)|(^((0\d{2,3})|(\(\d{3,4}\)))[-\s]?([2-9]\d{6,7})$)/
例項6:郵箱驗證
電子郵箱地址是開發中經常需要驗證的一種格式,一般郵箱的格式都是:郵箱名 @ 域名 . 域名字尾。
郵箱規則是:郵箱名一般要求字母或數字開頭,中間可以包括數字、字母、下劃線或槓;域名一般是多個數字、字母、下劃線或槓;域名字尾由2-5個字母組成,且可以是1-2個。
知道郵箱的格式和規則之後,可以寫出如下正規表示式:
/^[a-zA-Z0-9][\w-]{2,19}@[\w-]{2,}(\.[a-zA-Z]{2,5}){1,2}$/
分解一下表示式:
1. ^[a-zA-Z0-9] 表示郵箱名必須是字母或數字開頭;
2. [\w-]{2,19} 表示郵箱名可以包含數字、字母、下劃線或槓;
3. @ 郵箱分隔符
4. [\w-]{2,} 表示域名是2個以上的數字、字母、下劃線或槓;
5. (\\.[a-zA-Z]{2,5}){1,2}$ 表示結尾是1-2個域名字尾,域名字尾必須是 . 開頭。
具體實現程式碼如下:
<div class="form_Box"> <dl> <dt>郵箱:</dt> <dd><input type="text" id="verifyMail"><span></span></dd> </dl> </div> <script> //獲取input元素 var eInput = document.getElementById('verifyMail'); //在input元素上繫結change事件 eInput.addEventListener('change',function(event){ //獲取輸入值 var sValue = this.value; //宣告正規表示式 var reg = /^[a-zA-Z0-9][\w-]{2,19}@[\w-]{2,}(\.[a-zA-Z]{2,5}){1,2}$/; //獲取父級元素 var eParent = this.parentElement; //獲取input元素後的span元素,用於存放提示資訊 eSpan = eParent.getElementsByTagName('span')[0]; if(reg.test(sValue)){ //span元素上清除提示 eSpan.innerHTML = ''; }else{ //span元素上顯示提示 eSpan.innerHTML = '請輸入正確的郵箱地址'; } }); </script>
例項7:日期驗證
再來完成一個日期輸入框的驗證,比前面的日期驗證的表示式再稍微複雜一點。本例項中設定日期格式為四種:20.02.02、2020-12-12、2020/2/2、2020年10月2日。這四種格式都是有效日期,分析一下表示式規則:年是4位數字;中間的分隔符可以是 . 、 - 、/ 和 漢字 四種;月和日可以是1到2位數字。正規表示式如下。
/^(\d{4}|\d{2})(\-|\/|\.)\d{1,2}\2\d{1,2}$|^\d{4}年\d{1,2}月\d{1,2}日$/
來分解一下表示式。^(\d{4}|\d{2})(-|/|.)\d{1,2}\2\d{1,2}$ 是第一個分枝條件,表示20.02.02、2020-12-12、2020/2/2這三種格式。
- ^(\d{4}|\d{2}) 表示年是4個數字或2個數字開頭;
- (\-|\/|\.) 表示年月中間的分隔符可以是 . 、 - 、/ 這三種中的任意一種;
- \d{1,2} 表示月是1個或2個數字;
- \2 表示月日中間的分隔符。這是一個新知識點,叫做 後向引用 ,反斜槓後的數字表示和第幾個分組相同的匹配。 \2 作用是月日之間的分隔符要和年月之間的分隔符(即第2個分組 (\-|\/|\.) )的匹配一致。比如年和月之間用的是 - ,那麼月和日之間也必須是 - 分隔,這樣可以限制 2020-02/02 就是一個無效的匹配;
- \d{1,2}$ 表示日是1個或2個數字。
^\d{4}年\d{1,2}月\d{1,2}日$ 是第二個分枝條件,表示匹配 2020年10月2日 這種格式,讀者可以自己分解試試。具體實現程式碼如下:
<div class="form_Box"> <dl> <dt>日期:</dt> <dd><input type="text" id="verifyDate"><span></span></dd> </dl> </div> <script> //獲取input元素 var eInput = document.getElementById('verifyDate'); //在input元素上繫結change事件 eInput.addEventListener('change',function(event){ //獲取輸入值 var sValue = this.value; //宣告正規表示式 var reg = /^(\d{4}|\d{2})(\-|\/|\.)\d{1,2}\2\d{1,2}$|^\d{4}年\d{1,2}月\d{1,2}日$/; //獲取父級元素 var eParent = this.parentElement; //獲取input元素後的span元素,用於存放提示資訊 eSpan = eParent.getElementsByTagName('span')[0]; if(reg.test(sValue)){ //span元素上清除提示 eSpan.innerHTML = ''; }else{ //span元素上顯示提示 eSpan.innerHTML = '請輸入正確日期'; } }); </script>
筆者在這裡再貢獻一個嚴謹版的日期正規表示式,如下所示:
/^\d{4}(\-|\/|\.)(?:(?:0[1-9]|1[0-2])\1(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])\1(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)(\-|\/|\.)(?:02)\2(?:29)$/
此表示式限制格式只能是2020.12.02、2020-12-12、2020/02/02三種;年只能是4位數字,月和日必須是2位數字;月不能超過12;2月閏年才能有29。其中還有未提及的知識點,讀者可以複製使用也可以嘗試分解。
例項8:密碼強度校驗
先定義一下密碼的要求:密碼必須是6-16個字元;純數字或純字母強度為低;同時包含字母、數字、特殊符號中的兩種為中;同時包含字母、數字和特殊符號為高。
宣告三個正則變數,代表不同的強度,通過邏輯運算得出密碼強度。三個正則如下所示:
var weakReg = /^[\w!@#$%^&*?\(\)]{6,16}$/; var midReg = /^(((?=.*\d)(?=.*[!@#$%^&*?\(\)_-]))|((?=.*\d)(?=.*[a-zA-Z]))|((?=.*[!@#$%^&*?\(\)_-])(?=.*[a-zA-Z])))[\w!@#$%^&*?\(\)]{6,16}$/; var strongReg = /^(?=.*\d)(?=.*[a-zA-Z])(?=.*[!@#$%^&*?\(\)_-])[\w!@#$%^&*?\(\)]{6,16}$/;
這段正則我就不在此文進行分解,因為涉及的知識點暫時還沒說,可能又得多舉兩個例子,下次有空再在另外的正則文章中敘述。
具體實現程式碼如下:
<div class="form_Box"> <dl> <dt>密碼:</dt> <dd><input type="password" id="verifyPwd"><span></span></dd> </dl> </div> <script> //獲取input元素 var eInput = document.getElementById('verifyPwd'); //在input元素上繫結input事件 eInput.addEventListener('input',function(event){ //獲取輸入值 var sValue = this.value; //宣告正規表示式 var weakReg = /^[\w!@#$%^&*?\(\)]{6,16}$/; var midReg = /^(((?=.*\d)(?=.*[!@#$%^&*?\(\)_-]))|((?=.*\d)(?=.*[a-zA-Z]))|((?=.*[!@#$%^&*?\(\)_-])(?=.*[a-zA-Z])))[\w!@#$%^&*?\(\)]{6,16}$/; var strongReg = /^(?=.*\d)(?=.*[a-zA-Z])(?=.*[!@#$%^&*?\(\)_-])[\w!@#$%^&*?\(\)]{6,16}$/; //獲取父級元素 var eParent = this.parentElement; //獲取input元素後的span元素,用於存放提示資訊 eSpan = eParent.getElementsByTagName('span')[0]; eSpan.innerHTML = fnPower(sValue,strongReg,'強') || fnPower(sValue,midReg,'中') || fnPower(sValue,weakReg,'弱') || '密碼必須是6-16個字元'; }); //校驗密碼強度 function fnPower(str,reg,text){ if(reg.test(str)){ return text; }{ return null; } } </script>
例9:經典日期物件格式化
這裡有很經典的一個格式化日期時間的方法,多年以前用的人應該非常多。現在不提倡修改原生物件的原型,所以用的人比較少了。程式碼如下:
Date.prototype.format = function(format){ var o = { "M+" : this.getMonth()+1, //month "d+" : this.getDate(), //day "h+" : this.getHours(), //hour "m+" : this.getMinutes(), //minute "s+" : this.getSeconds(), //second "q+" : Math.floor((this.getMonth()+3)/3), //quarter "S" : this.getMilliseconds() //millisecond }; if(/(y+)/.test(format)){ format = format.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length)); } for(var k in o) { if(new RegExp("("+ k +")").test(format)){ format = format.replace(RegExp.$1, RegExp.$1.length==1 ? o[k] : ("00"+ o[k]).substr((""+ o[k]).length)); } } return format; }; //獲取日期物件 var dToday = new Date(); //輸出當前日期與時間,'yyyy-MM-dd hh:mm:ss'中間的分隔符可以隨意修改 console.log(dToday.format('yyyy-MM-dd hh:mm:ss'));
在此例項中,傳入格式化的字串 yyyy-MM-dd hh:mm:ss,y 表示年,M 表示月,d 表示日期,h 表示小時,m 表示分,s 表示秒;重複次數表示顯示的位數,yyyy 表示年顯示為2020(yy顯示20),MM 表示月顯示為 04(M顯示4)。- 和 : 是分隔符,可以修改。
這些字母能在日期物件中能替換成正確的日期時間,因為在物件 o 裡面,每一個字母都對應了相對獲取日期和時間的方法。如下程式碼段:
var o = { "M+" : this.getMonth()+1, //month "d+" : this.getDate(), //day "h+" : this.getHours(), //hour "m+" : this.getMinutes(), //minute "s+" : this.getSeconds(), //second "q+" : Math.floor((this.getMonth()+3)/3), //quarter "S" : this.getMilliseconds() //millisecond };
下面這段程式碼通過 if 條件語句判斷正則 /(y+)/ 在字串中是否存在。如果存在,替換符合正則的字串部分。
if(/(y+)/.test(format)){ format = format.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length)); }
這裡有用到一個新知識點 RegExp.$1。RegExp 是正規表示式物件,它有 RegExp.$1 - RegExp.$99 這99個分組匹配屬性,和例項7中說過的後向引用是相同概念。RegExp.$1 就是引用第一個分組相同的匹配。
所以 format.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length)) 中的 RegExp.$1 表示 (y+) 這一個分組的正則,即找到 yyyy。(this.getFullYear()+"").substr(4 - RegExp.$1.length) 表示日期物件獲取的年份,根據yyyy的長度取值。
下面的迴圈語句型別,也是通過 RegExp.$1 引用對應正則的字串,從物件 o 中通過new RegExp建立正則,獲取日期物件對應的值。
for(var k in o) { if(new RegExp("("+ k +")").test(format)){ format = format.replace(RegExp.$1, RegExp.$1.length==1 ? o[k] : ("00"+ o[k]).substr((""+ o[k]).length)); } }
比如 o 物件中第一個 "M+",建立的正則是 RegExp("(M+)"),即直接量的 /(M+)/。所以可以通過 this.getMonth()+1 獲取月份替換字串中的 MM。後面的以此類推。
寫到這裡,正則還有捕獲、零寬代言、貪婪和懶惰特性等內容沒有描述,我將放到下一篇關於正則的文章再來講解。同時部落格中有些知識描述得也不那麼清晰,還請讀者多多包涵。