從 例子 開始 入門 正則 表示式(-)

Mask_發表於2019-03-04

正則入門

  正則 是個難啃的骨頭,以前看著會正則的人 感覺都好牛逼。於是工作了2年了終於鼓起勇氣啃這個骨頭了。。

例子入手

  首先我們先看下相關的字元代表。我們先看這個例子。這個?就是驗證字串是否是數字。

let regex = /^[0-9]+$/;
let number = `123`;
let string = `abc`;
regex.test(number); // true
regex.test(string); // false
複製程式碼

可能很多人這時用到了百度谷歌一下然後複製過去直接用就OK了,但是這樣沉澱不到東西,所以我們來靜下心看看這個正則到底什麼意思,首先我們要了解的是相關的

  • ^ :脫字元,匹配開頭,在多行匹配中匹配行開頭,有時也表示求反的概念。
  • $ :美元符號, 匹配結尾,在多行匹配中匹配行結尾。
  • {m,} 表示至少出現m次。
  • {m} 等價於{m,m},表示出現m次。
  • +: 等價於{1,},表示出現至少一次。記憶方式:加號是追加的意思,得先有一個,然後才考慮追加。
  • *:等價於{0,},表示出現任意次,有可能不出現。記憶方式:看看天上的星星,可能一顆沒有,可能零散有幾顆,可能數也數不過來。

可能這時你有些不理解 [0-9],其實他等價於 [0123456789] ,在正則裡可以縮寫所以為 [0-9], 同理[a-z],[A-Z]也是同樣的道理。為什麼使用正則因為他書寫簡單,我們還可以簡化,讓我們等下看看接下來的這些字元,思考下怎麼繼續簡化。

那我們大概能猜到這個意思代表什麼了,從 開頭(^) 到 結尾($) 0-9([0-9]) 出現 至少一次 (+) , 所以就很好理解了,為什麼這個是驗證數字的想必就能理解了。
接下來我們再來看一些特殊字元:

  • d就是[0-9]。表示是一位數字。記憶方式:其英文是digit(數字)。
  • D就是[^0-9]。表示除數字外的任意字元。
  • w就是[0-9a-zA-Z_]。表示數字、大小寫字母和下劃線。記憶方式:w是word的簡寫,也稱單詞字元。
  • W是[^0-9a-zA-Z_]。非單詞字元。
  • s是[ v

    f]。表示空白符,包括空格、水平製表符、垂直製表符、換行符、回車符、換頁符。記憶方式:s是space character的首字母。

  • S是[^ v

    f]。 非空白符。

  • .就是[^

    u2028u2029]。萬用字元,表示幾乎任意字元。換行符、回車符、行分隔符和段分隔符除外。記憶方式:想想省略號…中的每個點,都可以理解成佔位符,表示任何類似的東西。

  好的我們看到了 d 其實就是 [0-9],此時忽然恍然大悟,原來上面的正則還能簡化:

let regex = /^d+$/; // /^[0-9]+$/;
複製程式碼

這時我們大概 已經懂得這個正則代表什麼東西了,之後再出現驗證使用者輸入的是不是數字,就別再百度了,分分鐘就寫出來。

舉一反三

  我們已經瞭解之前的這個例子後,大概能推敲如何實現驗證全是字母:

let regex = /^[a-z]+$/;
let string = `abc`;
let number = `123`;
regex.test(number); //false
regex.test(string);//true
複製程式碼

正則是區分大小寫字母的,所以,我們要驗證大寫字母的時大概是這樣:

let regex = /^[A-Z]+$/;
let string = `abc`;
let STRING = `ABC`
let number = `123`;
regex.test(number); //false
regex.test(string);//false
regex.test(STRING); //true
複製程式碼

好了我們已經反二了,接下來我們來反三,即是大寫字母又是小寫字母,怎麼去寫?

let regex = /^[a-zA-Z]+$/
複製程式碼

估計到這裡我們都已經算入門了,不是很複雜的正則都可以自己去寫了。

考驗

接下來我們來看一些常用需求:

正則 驗證 手機 。

手機號碼是幾位,emmmm,等下我先數數 183 XXX XXX XX ,噗,11位,好吧當我沒說。那我們分析下,手機號, 首先全部都是數字, 開頭第一位一定是 數字 1 ,然後只要滿足 11位就可以了,我們已經把需求整理清楚了,如果我們用 js 去寫會怎麼寫?我這裡隨意寫一寫,可能有更好的方式

const isPhone = (number) => {
    const len = number.length;
    if (typeof number !== `string` || len !== 11  || number[0] !== `1`) {
        return false;
    }

    for (let i = 0; i < len; i++) {
        if (isNaN(number[i])) return false;
    }

    return true;
}

console.log(IsPhone(`18367490590`)); //true


複製程式碼

可見一個 js 書寫是多麼麻煩,也可能是我的解決方式不是很牛逼,隨便寫寫,各位有什麼好的解決方案也可以給我評論。。扯遠了。現在我們來看看要是用正則怎麼寫?

let regex  = /^1d{10}$/;
複製程式碼

一行程式碼搞定。就是這麼簡單,讓我們分析一下。

  • ^ 開頭匹配
  • 1 開頭沒毛病
  • d 表示 [0-9] 代表必須是數字
  • {10} 也是 {10, 10} 表示 [0-9]出現10次,加上1 也就是說 11位。
  • $ 結尾匹配沒毛病。
    以上一行程式碼就搞定了。很簡便其實分析下也不是很難。

正則 驗證 郵箱 。

我就不寫什麼 js 的版本了,有興趣的同學可以自己嘗試寫寫。我們看看郵箱的正則應該是有這麼幾個需求的:

  • xxx@xxx.xxx
  • @ 前需要有任意字元
  • 郵箱 有 @ 符號。
  • @後有任意字元
  • 要有 .
  • . 後跟任意字元
let regex = /^w+@w+.w+/;
複製程式碼

簡單分析一下:

  • w我們知道是[0-9a-zA-Z_]下劃線
  • + 代表至少出現一次 好比 {1,}
  • @ 必須需要。
  • . 這裡要注意下,因為 . 是特殊正則字元, 代表萬用字元, 我們這裡需要的是 “.” 字串,所以加了 進行轉譯

補充案例

  之前的例子們大概動了一些東西,讓我們再來看幾個例子。

匹配16進位制顏色值

大概是這樣:

#ffbbad
#Fc01DF
#FFF
#ffE

寫法:

let regex = /#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})/g;
複製程式碼

分析:
開頭是#號,表示一個16進位制字元,可以用字元組[0-9a-fA-F]。然後 {6} 代表 出現6 次,這時候你可能有點迷
這個代表什麼 稍等引出這個 | 是分支的概念。再說說後面其實也很好理解 字元組[0-9a-fA-F] 出現3次。

  • | 分支,其實可以理解為這個是程式設計中的或,很容易理解了。那麼,我們知道或者是惰性的,一個成立不向下執行,這裡其實也一樣。

讓我們再來一個案例:

驗證 匹配 yyyy-mm-dd : 2018-10-20

正則如下:

var regex = /^d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]d|3[01])$/;
複製程式碼

分析一波:

  • 年 d{4} [0-9]出現4次。
  • 月 共12個月, 十位0的話就是 [1-9]月,十位1的話就是 [0-2]個月。
  • 日 最多31天 ,十位0的話就是 [1-9]天,十位1,十位2就是[0-9] 3的話只有0或者1。

結語。

正則是個大工程這裡只是一些簡單的正則,比如還有惰性匹配等 我們還沒有見到, 在後面的系列中我會慢慢的加入進去。未完…

相關文章