JS正則,看這里就夠了

寫在前面

正則的使用蓬戚,相信大家工作中常用到的莫過于夸楣,表單驗證:驗證用戶輸入的內(nèi)容是否符合我們設(shè)定的規(guī)則,例如:郵箱、電話子漩、密碼...豫喧,當(dāng)然公司業(yè)務(wù)不同,手寫能力強(qiáng)同學(xué)也可以用數(shù)據(jù)采集:在一堆數(shù)據(jù)中把我們需要的數(shù)據(jù)獲取到幢泼,今天順帶總結(jié)一下,例如::

  • URL傳參(問號傳參) 從列表頁到詳細(xì)頁(或者其他的頁面),我們點擊不同的列表,在詳細(xì)頁面看到的內(nèi)容也不同,但是詳細(xì)頁是同一個頁面,想要展示不同的內(nèi)容,需要把URL地址中的,?后面?zhèn)鬟f進(jìn)來的參數(shù)獲取到,通過傳遞過來的參數(shù)值的不一樣展示不同的內(nèi)容
  • 信息采集:把一些數(shù)據(jù)轉(zhuǎn)變?yōu)槲覀兿胍母袷?例如:"2018-4-3 12:14:00" ->"2016年04月03日"

今天順帶總結(jié)一下紧显;
正則是什么
正則就是用來處理字符串的:匹配字符串的格式是否符合既定的格式(正則的匹配)、把一個字符串中符合既定格式的內(nèi)容獲取到(正則的捕獲)缕棵;
test和exec是正則里面的方法
test->匹配

   var reg = /\d/;//-> \d一個0-9之間的數(shù)字 ->包含一個0-9之間的數(shù)字的規(guī)則
       console.log(reg.test("2016"));//->true
       console.log(reg.test("duff990fff"));//->true
       console.log(reg.test("dufffff"));//->false

exec->捕獲

   var reg = /\d/g;
       console.log(reg.exec("2016"));//->["2", index: 0, input: "2016"]
       console.log(reg.exec("2016"));//->["0"...]
       console.log(reg.exec("2016"));//->["1"...]
       console.log(reg.exec("2016"));//->["6"...]

正則的組成
每個正則都是由元字符和修飾符兩部分組成孵班, “/”里面的 內(nèi)容稱為元字符 “/”
[修飾符]g、i招驴、m

    g(global)->全局匹配
    i(ignoreCase)->忽略大小寫匹配
    m(multiline)->換行匹配

正則常用的元字符

以下列出的都是常用的元字符篙程,如果是不了解的童鞋需要,浪費你10分鐘時間記一下忽匈,終身受益哈~
元字符:只要在//之間包含的所有的字符都是元字符

1)具有特殊意義的元字符

      \d -> 匹配一個0-9的數(shù)字,相當(dāng)于[0-9],和它相反的是\D ->匹配一個除了0-9的任意字符
       \w -> 匹配一個0-9房午、a-z、A-Z丹允、_的數(shù)字或字符,相當(dāng)于[0-9a-zA-Z_]
       \s -> 匹配一個空白字符(空格、制表符...)
       \b -> 匹配一個單詞的邊界
       \t -> 匹配一個制表符
       \n -> 匹配一個換行
       . -> 匹配一個除了\n以外的任意字符
       ^ -> 以某一個元字符開頭
       $ -> 以某一個元字符結(jié)尾
       \ -> 轉(zhuǎn)義字符
       x|y -> x或者y的一個
       [xyz] -> x袋倔、y雕蔽、z中的任意一個
       [^xyz] -> 除了xyz中的任意一個字符
       [a-z] -> 匹配a-z中的任意一個字符
       [^a-z] -> 匹配除了a-z中的任意一個字符
       () -> 正則中的分組

2)代表出現(xiàn)次數(shù)的"量詞元字符"

    ->+ : 出現(xiàn)一到多次
    ->* : 出現(xiàn)零到多次
    ->? : 出現(xiàn)零到一次
    ->{n} : 出現(xiàn)n次
    ->{n,} : 出現(xiàn)n到多次
    ->{n,m} : 出現(xiàn)n-m次

小試牛刀

-> ^/$
       var reg = /\d+/;//->包含一到多個數(shù)字(0-9)即可
       console.log(reg.test("duffy2016"));//->true

       reg = /^\d+$/;//->只能是一到多個數(shù)字
       console.log(reg.test("duffy2016"));//->false
       console.log(reg.test("2016"));//->true
-> .
       var reg = /^2.6$/;
       console.log(reg.test("2.6"));//->true
       console.log(reg.test("2@6"));//->true
    
       reg = /^2\.6$/;//->\是轉(zhuǎn)義字符:把.這個特殊意義(任意字符)的元字符轉(zhuǎn)變?yōu)橹淮肀旧硪饬x(小數(shù)點)的一個普通元字符
       console.log(reg.test("2.6"));//->true
       console.log(reg.test("2@6"));//->false
//->[]
    //->在中括號中出現(xiàn)的所有字符(不管之前代表什么意思),在這里都是只代表本身的意思
    //var reg = /^[2.3]$/;//->.這里只代表小數(shù)點,不是任意字符了
    //reg = /^[\dz]$/;//->\d本身整體就是0-9之間的數(shù)字,在這里還是這個意思
//->在中括號中出現(xiàn)的兩位數(shù)不是一個兩位數(shù),而是左邊或者右邊的
//var reg = /^[10-23]$/;//->1或者0-2或者3
在中括號中"-"具有連字符的作用,如果只想表示-,需要把其放在末尾
    //var reg = /^[12-]$/;

    //->中括號本身也有特殊的意思,如果需要只代表中括號本身的意思,需要進(jìn)行轉(zhuǎn)義
    //var reg = /^\[\d+\]$/;//->"[200]"
//->x|y
//var reg = /^1|2$/;//->和這個有區(qū)別:/^[12]$/
//->1宾娜、2批狐、12
    //var reg = /^10|28$/;
    //->10、28、1028嚣艇、102承冰、108、128食零、028 ->不是我們想要的那個10或者28了

()分組:把一個大正則劃分成幾個小正則
1)改變正則的默認(rèn)優(yōu)先級

//var reg = /^(10|28)$/;//->10或者28

2)分組的第二個作用:分組引用

    "wood" "foot" "week" "feel" "door" "food" "good" "cool"...
    var reg = /^[a-z]([a-z])\1[a-z]$/i;//->\1出現(xiàn)和第一個分組一模一樣的內(nèi)容

5困乒、創(chuàng)建一個正則也有兩種方式:字面量方式、實例創(chuàng)建的方式

    //->實例創(chuàng)建第一參數(shù)值是字符串
    //->想要和字面量方式保持統(tǒng)一的話,對于\d \w \n...這些都需要多加一個\,使其\d具有自己的特殊的意義
  var reg = /^\d+$/ig;
console.log(reg.test("2016"));//->true
reg = new RegExp("^\d+$", "ig");
console.log(reg.test("2016"));//->false
reg = new RegExp("^\\d+$", "ig");
console.log(reg.test("2016"));//->true
    //->對于[]贰谣、()這類的是沒有區(qū)別的
    //    var reg = /^[0-9]$/;
    //    console.log(reg.test("0"));//->true
    //    reg = new RegExp("^[0-9]$");
    //    console.log(reg.test("0"));//->true

    //->在實例創(chuàng)建的方式中,我們只要出現(xiàn)\,基本上都是要寫\\的
    //    var reg = /^\[100\]$/;
    //    console.log(reg.test("[100]"));//->true
    //    reg = new RegExp("^\[100\]$");
    //    console.log(reg.test("[100]"));//->false
    //    reg = new RegExp("^\\[100\\]$");
    //    console.log(reg.test("[100]"));//->true

當(dāng)一個正則表達(dá)式中需要把一個變量的值作為一個動態(tài)的規(guī)則:我們只能使用實例創(chuàng)建的方式
// var reg = /^duffy"+num+"peixun$/;//->在//之間包起來的都是元字符,有的是特殊的,有的就是代表本身意思的 ->以z開頭,hufeng,出現(xiàn)一到多個",nu,出現(xiàn)一個到一個m,",peixun ->總之一句話:字面量方式中不存在什么字符串娜搂,也就沒有所謂的字符串拼接,把變量的值拼接過來這一說了

    //    console.log(reg.test("duffy2016peixun"));//->false

    //    var num = 2016;
    //    var reg = new RegExp("^duffy" + num + "peixun$");
    //    console.log(reg.test("duffy2016peixun"));//->true
//字面量創(chuàng)建出來的是基本數(shù)據(jù)類型的值(不是嚴(yán)謹(jǐn)?shù)膶嵗?因為不能使用instanceof 檢測是否是Number的實例),實例創(chuàng)建出來的是對象數(shù)據(jù)類型的值
//    var num = 12;
//    var num = new Number(12);

常用的正則表達(dá)式

1吱抚、手機(jī)號:11位數(shù)字百宇、都是以1開頭的

var reg = /^1\d{10}$/;

2、真實姓名(中國):兩到四位的漢字

var reg = /^[\u4e00-\u9fa5]{2,4}$/;

3秘豹、驗證郵箱

// 1633397595@qq.com
// 1633397595@163.com.cn
// 1633397595@163.com
// duffy_youxiang@tengxu.cn
//var reg7 = /^[\w.-]+@$/  //@分解兩邊 左邊任意,\w 數(shù)字携御,大小寫字符_ - . 右邊
var reg7 = /^[\w.-]+@([1-9]|[a-z]|[A-Z])+(\.[A-Za-z]{2,4}){1,2}$/
console.log(reg7.test('1633397595@qq.com'))

4、驗證有效數(shù)字的

  0 -12 -12.3 -12.0 12.3 12.0
    ->可能出現(xiàn)"-"也可能不出現(xiàn),出現(xiàn)的話只能出現(xiàn)一次
    ->整數(shù)部分是一到多個數(shù)字,但是兩位數(shù)及以上的話不能以0開頭
    ->小數(shù)部分可能有可能沒有,一但有必須是 .后面跟一位或者多位數(shù)字
    var reg = /^-?(\d|([1-9]\d+))(\.\d+)?$/;

5既绕、年齡:18-65之間

    18-19  /^1(8|9)$/
    20-59  /^[2-5]\d$/
    60-65  /^6[0-5]$/
    var reg = /^((18|19)|([2-5]\d)|(6[0-5]))$/;

正則的捕獲

正則的捕獲分為兩個階段:
匹配:首先驗證字符串和正則是否匹配,不匹配的話捕獲到的結(jié)果為null

       var str = "dafei";
       var reg = /\d+/;
       console.log(reg.exec(str));//->null

捕獲:把正則匹配到的內(nèi)容捕獲到:捕獲到的結(jié)果是一個數(shù)組,數(shù)組第一項是當(dāng)前正則匹配捕獲的內(nèi)容,index:捕獲的開始索引位置,input:捕獲的原始字符串
每一次執(zhí)行exec只能捕獲到一個匹配的,想把所有匹配的都捕獲到,至少要執(zhí)行多次 ->但是一般情況下因痛,我們不管執(zhí)行多少次,每一次捕獲的內(nèi)容都是和第一次一模一樣岸更,后面的2017是捕獲不到的
"正則捕獲的懶惰性"

       var str = "duffy2016peixun2017";
       var reg = /\d+/;
       console.log(reg.exec(str));//->["2016", index: 7, input: "duffy2016peixun2017"]
       console.log(reg.exec(str));//->["2016"...]

為啥會出現(xiàn)懶惰性? reg.lastIndex:正則每一次捕獲的時候,在字符串中開始查找的索引, 正則每一次捕獲結(jié)束后,默認(rèn)的沒有把lastIndex值進(jìn)行修改,lastIndex一直是零,導(dǎo)致第二次捕獲還是從字符串的起始位置開始查找,導(dǎo)致每一次捕獲的都是第一個和正則匹配的

    var str = "duffy2016peixun2017";
       var reg = /\d+/;
       console.log(reg.lastIndex);//->0 捕獲的時候是從字符串開始的位置進(jìn)行查找的
       console.log(reg.exec(str));//->["2016"...]
       console.log(reg.lastIndex);//->0 第二次捕獲的話還是從字符串索引為零的位置開始查找
       console.log(reg.exec(str));//->["2016"...]

有n個的匹配的就需要執(zhí)行n次exec這個方法,比較的麻煩,生活如此美好鸵膏,何必這么麻煩? ->字符串中提供了一個叫做match的方法,這個方法可以一次執(zhí)行把所有匹配的捕獲到

       var str = "duffy2016peixun2017";
       var reg = /\d+/g;//->不管用哪個方法,g是不能少的
       console.log(str.match(reg));//->["2016", "2017"]

但是match也有自己的局限性? 如果正則中出現(xiàn)分組,而且需要執(zhí)行多次exec才能全部捕獲的,使用match不能把分組的內(nèi)容捕獲到.最佳解決方案 ---replace,replace天生為正則而生

實戰(zhàn)

格式化時間字符串

var str = "2016-04-03";//->"2016年04月03日"
let reg = /^([1-9]\d{3})-(0?[1-9]|1[1-2])-([02]\d|[3][0-1])$/
console.log(reg.test(str))
str.replace(reg,function(){
  console.log(arguments)
  return arguments[1] + '年' + arguments[2] + '月' + + arguments[3] + '日'
})

function format(str) {
  var reg = /^([1-9]\d{3})-(0?[1-9]|1[1-2])-([02]\d|[3][0-1])$/g
  if (!reg.test(str)) return '輸入日期格式不合法'
  return (str.replace(reg,function(){
    // console.log(arguments)
    return arguments[1] + '年' + arguments[2] + '月' + + arguments[3] + '日'
  }))
}
console.log(format('2018-12-30'))   -> '2018年12月30日

數(shù)字大寫轉(zhuǎn)換

   var str = "123678";//->"壹貳叁陸柒捌"
       var ary = ["零", "壹", "貳", "叁", "肆", "伍", "陸", "柒", "捌", "玖"];
       str = str.replace(/\d/g, function () {
           //console.log(arguments[0]);//->每一次捕獲到的內(nèi)容(我們要的數(shù)字)
           return ary[arguments[0]];
       });
       console.log(str);

簡易模板引擎實現(xiàn)的原理

var data = ['duffy', '27', 'china', 'javascript']
var str = "my name is {0}怎炊,my age is {1}谭企,i com from {2},i can do {3}~~";

var reg = /\{(\d)\}/g
console.log(reg.test(str))
str = str.replace(reg, function(){
  return data[arguments[1]]
})
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末评肆,一起剝皮案震驚了整個濱河市债查,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瓜挽,老刑警劉巖盹廷,帶你破解...
    沈念sama閱讀 211,561評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異久橙,居然都是意外死亡俄占,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評論 3 385
  • 文/潘曉璐 我一進(jìn)店門淆衷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來缸榄,“玉大人,你說我怎么就攤上這事祝拯∩醮” “怎么了?”我有些...
    開封第一講書人閱讀 157,162評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長鹰贵。 經(jīng)常有香客問我晴氨,道長,這世上最難降的妖魔是什么碉输? 我笑而不...
    開封第一講書人閱讀 56,470評論 1 283
  • 正文 為了忘掉前任籽前,我火速辦了婚禮,結(jié)果婚禮上腊瑟,老公的妹妹穿的比我還像新娘聚假。我一直安慰自己,他們只是感情好闰非,可當(dāng)我...
    茶點故事閱讀 65,550評論 6 385
  • 文/花漫 我一把揭開白布膘格。 她就那樣靜靜地躺著,像睡著了一般财松。 火紅的嫁衣襯著肌膚如雪瘪贱。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,806評論 1 290
  • 那天辆毡,我揣著相機(jī)與錄音菜秦,去河邊找鬼。 笑死舶掖,一個胖子當(dāng)著我的面吹牛球昨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播眨攘,決...
    沈念sama閱讀 38,951評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼主慰,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了鲫售?” 一聲冷哼從身側(cè)響起共螺,我...
    開封第一講書人閱讀 37,712評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎情竹,沒想到半個月后藐不,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,166評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡秦效,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,510評論 2 327
  • 正文 我和宋清朗相戀三年雏蛮,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片棉安。...
    茶點故事閱讀 38,643評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡底扳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出贡耽,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 34,306評論 4 330
  • 正文 年R本政府宣布蒲赂,位于F島的核電站阱冶,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏滥嘴。R本人自食惡果不足惜木蹬,卻給世界環(huán)境...
    茶點故事閱讀 39,930評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望若皱。 院中可真熱鬧镊叁,春花似錦、人聲如沸走触。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽互广。三九已至敛腌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間惫皱,已是汗流浹背像樊。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留旅敷,地道東北人生棍。 一個月前我還...
    沈念sama閱讀 46,351評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像媳谁,于是被迫代替她去往敵國和親涂滴。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,509評論 2 348

推薦閱讀更多精彩內(nèi)容