1. 程式人生 > >【前端知識體系-JS相關】10分鐘搞定JavaScript正則表示式高頻考點

【前端知識體系-JS相關】10分鐘搞定JavaScript正則表示式高頻考點

1.正則表示式基礎

1.1 建立正則表示式

1.1.1 使用一個正則表示式字面量

const regex = /^[a-zA-Z]+[0-9]*\W?_$/gi;

1.1.2 呼叫RegExp物件的建構函式

const regex = new RegExp(pattern, [, flags])

1.1.3 特殊字元

 - ^ 匹配輸入的開始
 - $ 匹配輸入的結束
 - \* 0次或多次  {0,}
 - \+ 1次或多次  {1,}
 - ?
   - 0次或者1次 {0,1}。
   - 用於先行斷言
   - 如果緊跟在任何量詞 *、 +、? 或 {} 的後面,將會使量詞變為非貪婪
     - 對 "123abc" 用 /\d+/ 將會返回 "123",
     - 用 /\d+?/,那麼就只會匹配到 "1"。
 - . 匹配除換行符之外的任何單個字元
 - (x)  匹配 'x' 並且記住匹配項
 - (?:x)  匹配 'x' 但是不記住匹配項
 - x(?=y)  配'x'僅僅當'x'後面跟著'y'.這種叫做正向肯定查詢。
 - x(?!y)  匹配'x'僅僅當'x'後面不跟著'y',這個叫做正向否定查詢。
 - x|y  匹配‘x’或者‘y’。
 - {n}  重複n次
 - {n, m}  匹配至少n次,最多m次
 - [xyz]   代表 x 或 y 或 z
 - [^xyz]  不是 x 或 y 或 z
 - \d  數字
 - \D  非數字
 - \s  空白字元,包括空格、製表符、換頁符和換行符。
 - \S  非空白字元
 - \w  單詞字元(字母、數字或者下劃線)  [A-Za-z0-9_]
 - \W  非單字字元。[^A-Za-z0-9_]
 - \3  表示第三個分組
 - \b   詞的邊界
   - /\bm/匹配“moon”中得‘m’;
 - \B   非單詞邊界

1.2 使用正則表示式的方法

  • exec 一個在字串中執行查詢匹配的RegExp方法,它返回一個數組(未匹配到則返回null)。
  • test 一個在字串中測試是否匹配的RegExp方法,它返回true或false。
  • match 一個在字串中執行查詢匹配的String方法,它返回一個數組或者在未匹配到時返回null。
  • search 一個在字串中測試匹配的String方法,它返回匹配到的位置索引,或者在失敗時返回-1。
  • replace 一個在字串中執行查詢匹配的String方法,並且使用替換字串替換掉匹配到的子字串。
  • split 一個使用正則表示式或者一個固定字串分隔一個字串,並將分隔後的子字串儲存到陣列中的String方法。

1.2.1 正則物件的三個方法

        //①test()判斷字串中是否出現某個字串,返回布林值
        var re = /abc/;
        var str = '00abc66';
        console.log(re.test(str));  // true
        //②exec()查詢並返回字串中指定的某個字串,只匹配一次
        var re = /abc/;
        var str = 'a0bc88abc00abc';
        console.log(re.exec(str));  // ["abc", index: 6, input: "a0bc88abc00abc", groups: undefined]
        //③compile()方法用於改變正則匹配的內容
        var re = /ab/;
        var str = "aabcdef";
        console.log(re.test(str));  //true
        re.compile(/bd/);
        console.log(re.test(str));  //false
        re.compile('66');
        console.log(re.test(str));  //false

1.2.2 字串中與正則相關的方法

        //①search()方法,返回符合條件的字串首次出現的位置(下標)
        var re = /abc/;
        var str = '00abc66';
        console.log(str.search(re));        // 2
        //②match()方法,返回查詢的結果,如果查詢不到返回NULL
        console.log(str.match(re));         // ["abc", index: 2, input: "00abc66", groups: undefined]
        //③replace()方法,將匹配到的內容替換成指定內容
        console.log(str.replace(re, "*"));
        //④split()方法,將字串分割成字串陣列
        console.log(str.split(re));

1.3 正則表示式子表示式相關

1.3.1 子表示式

在正則表示式中,通過一對圓括號括起來的內容,我們就稱之為“子表示式”。如:var re = /\d(\d)\d/;

1.3.2 捕獲

在正則表示式中,子表示式匹配到相應的內容時,系統會自動捕獲這個行為,然後將子表示式匹配到的內容放入系統的快取區中。我們把這個過程就稱之為“捕獲”。

1.3.3 反向引用

在正則表示式中,我們可以使用\n(n>0,正整數,代表系統中的緩衝區編號)來獲取緩衝區中的內容,我們把這個過程就稱之為“反向引用”。

    var str = "d1122jj7667h6868s9999";
    //查詢AABB型的數字
    console.log(str.match(/(\d)\1(\d)\2/)); //1122
    //查詢ABBA型的數字
    console.log(str.match(/(\d)(\d)\2\1/)); //7667
    //查詢ABAB型的數字
    console.log(str.match(/(\d)(\d)\1\2/)); //6868
    //查詢四個連續相同的數字
    console.log(str.match(/(\d)\1\1\1/));   //9999

1.4 限定符

[!NOTE]
限定符可以指定正則表示式的一個給定字元必須要出現多少次才能滿足匹配。

    *:匹配前面的子表示式零次或多次,0到多
    +:匹配前面的子表示式一次或多次,1到多
    ?:匹配前面的子表示式零次或一次,0或1
    {n}:匹配確定的 n 次 
    {n,}:至少匹配 n 次 
    {n,m}:最少匹配 n 次且最多匹配 m 次

[!WARNING]
注意:針對於{n,m},正則在匹配到一個符合多種次數的字串時,優先匹配次數多的,即能匹配到m次就不會匹配n次,這就是貪婪模式(預設)。

如果在其後加?即{n,m}?則會更改為非貪婪模式(惰性模式),則此時正則優先匹配n次。

    var str = "aa1a22a333a6a8a";
    console.log(str.match(/a\d*/));      //a
    console.log(str.match(/a\d+/));      //a1
    console.log(str.match(/a\d?/));      //a
    console.log(str.match(/a\d{3}/));    //a333
    console.log(str.match(/a\d{2,}/));   //a22
    console.log(str.match(/a\d{1,3}/));  //a1
    console.log(str.match(/a\d{1,3}?/)); //a1

    //貪婪模式加深理解,案例如下:
    //貪婪模式下最開始的'a2就符合條件',但是它會返回'a22'
    //注意:它是在遇到一個同時符合多個次數條件的字串時,取符合次數多字串
    var str = "a22aa1a333a6a8a";
    console.log(str.match(/a\d{1,3}/));   //a22
    console.log(str.match(/a\d{1,3}/g));  //a22 a1 a333 a6 a8
    console.log(str.match(/a\d{1,3}?/));  //a2
    console.log(str.match(/a\d{1,3}?/g)); //a2 a1 a3 a6 a8

1.5 定位符

[!NOTE]
定位符可以將一個正則表示式固定在一行的開始或結束。也可以建立只在單詞內或只在單詞的開始或結尾處出現的正則表示式。

^ (脫字元):匹配輸入字串的開始位置
$:匹配輸入字串的結束位置
\b:匹配一個單詞邊界
\B:匹配非單詞邊界

1.6 正則表示式的匹配模式(修飾符)

[!NOTE]
表示正則匹配的附加規則,放在正則模式的最尾部。修飾符可以單個使用,也可以多個一起使用。

  • ①g全域性匹配,找到所有匹配,而不是在第一個匹配後停止
  • ②i匹配全部大小寫
  • ③m多行,將開始和結束字元(^和$)視為在多行上工作(也就是,分別匹配每一行的開始和結束(由\n或\r分割),而不只是只匹配整個輸入字串的最開始和最末尾處。
  • ④s與m相反,單行匹配
    var re = /^[a-z]/gim;   //可組合使用

1.7 轉義字元

[!NOTE]
因為在正則表示式中 . +  等屬於表示式的一部分,但有時也需要匹配這些特殊字元,所以,需要使用反斜槓對特殊字元進行轉義。

  需要轉義的字元:
  點號.
  小括號()
  中括號[]
  左斜槓/
  右斜槓\
  選擇匹配符|
  
  * 
  ?
  {}
  + 
  $
  ^

2. 正則練習題

2.1 匹配結尾的數字

/\d+$/g

2.2 統計空格個數

字串內如有空格,但是空格的數量可能不一致,通過正則將空格的個數統一變為一個。

let reg = /\s+/g
str.replace(reg, " ");

2.3 判斷字串是不是由數字組成

str.test(/^\d+$/);

2.4 電話號碼正則

  • 區號必填為3-4位的數字
  • 區號之後用“-”與電話號碼連線電話號碼為7-8位的數字
  • 分機號碼為3-4位的數字,非必填,但若填寫則以“-”與電話號碼相連線
/^\d{3,4}-\d{7,8}(-\d{3,4})?$/

2.5 手機號碼正則表示式

正則驗證手機號,忽略前面的0,支援130-139,150-159。忽略前面0之後判斷它是11位的。

/^0*1(3|5)\d{9}$/

2.6 使用正則表示式實現刪除字串中的空格

funtion trim(str) {
  let reg = /^\s+|\s+$/g
  return str.replace(reg, '');
}

2.7 限制文字框只能輸入數字和兩位小數點等等

/^\d*\.\d{0,2}$/

2.8 只能輸入小寫的英文字母和小數點,和冒號,正反斜槓(:./)

/^[a-z\.:\/\\]*$/

2.9 替換小數點前內容為指定內容

例如:infomarket.php?id=197 替換為 test.php?id=197

var reg = /^[^\.]+/;
var target = '---------';
str = str.replace(reg, target)

2.10 只匹配中文的正則表示式

/[\u4E00-\u9FA5\uf900-\ufa2d]/ig

2.11 返回字串的中文字元個數

先去掉非中文字元,再返回length屬性。

function cLength(str){
  var reg = /[^\u4E00-\u9FA5\uf900-\ufa2d]/g;
  //匹配非中文的正則表示式
  var temp = str.replace(reg,'');
  return temp.length;
}

2.12 正則表示式取得匹配IP地址前三段

只要匹配掉最後一段並且替換為空字串就行了

function getPreThrstr(str) {
  let reg = /\.\d{1,3}$/;
  return str.replace(reg,'');
}

2.13 匹配ul標籤之間的內容

/<ul>[\s\S]+?</ul>/i

2.14 用正則表示式獲得檔名

c:\images\tupian\006.jpg

可能是直接在碟符根目錄下,也可能在好幾層目錄下,要求替換到只剩檔名。
首先匹配非左右斜線字元0或多個,然後是左右斜線一個或者多個。

function getFileName(str){
  var reg = /[^\\\/]*[\\\/]+/g;
  // xxx\ 或是 xxx/
  str = str.replace(reg,'');
  return str;
}

2.15 絕對路徑變相對路徑

"http://23.123.22.12/image/somepic.gif"轉換為:"/image/somepic.gif"

var reg = /http:\/\/[^\/]+/;
str = str.replace(reg,"");

2.16 使用者名稱正則

用於使用者名稱註冊,,使用者名稱只 能用 中文、英文、數字、下劃線、4-16個字元。

/^[\u4E00-\u9FA5\uf900-\ufa2d\w]{4,16}$/

2.17 匹配英文地址

規則如下:
包含 "點", "字母","空格","逗號","數字",但開頭和結尾不能是除字母外任何字元。

/^[a-zA-Z][\.a-zA-Z,0-9]*[a-zA-Z]$/

2.18 正則匹配價格

開頭數字若干位,可能有一個小數點,小數點後面可以有兩位數字。

/^\d+(\.\d{2})?$/

2.19 身份證號碼的匹配

身份證號碼可以是15位或者是18位,其中最後一位可以是X。其它全是數字

/^(\d{14}|\d{17})(X|x)$/

2.20 單詞首字母大寫

每單詞首字大寫,其他小寫。如blue idea轉換為Blue Idea,BLUE IDEA也轉換為Blue Idea

function firstCharUpper(str) {
  str = str.toLowerCase();
  let reg = /\b(\w)/g;
  return str.replace(reg, m => m.toUpperCase());
}

2.21 正則驗證日期格式

yyyy-mm-dd格式, 4位數字,橫線,1或者2位數字,再橫線,最後又是1或者2位數字。

/^\d{4}-\d{1,2}-\d{1,2}$/

2.22 去掉檔案的字尾名

www.abc.com/dc/fda.asp 變為 www.abc.com/dc/fda

function removeExp(str) {
  return str.replace(/\.\w$/,'')
}

2.23 驗證郵箱的正則表示式

開始必須是一個或者多個單詞字元或者是-,加上@,然後又是一個或者多個單詞字元或者是-。然後是點“.”和單詞字元和-的組合,可以有一個或者多個組合。

/^[\w-]+@\w+\.\w+$/

2.24 正則判斷標籤是否閉合

標籤可能有兩種方式閉合,自閉和或者對稱閉合的方式。

/<([a-z]+)(\s*\w*?\s*=\s*".+?")*(\s*?>[\s\S]*?(<\/\1>)+|\s*\/>)/i

2.25 正則判斷是否為數字與字母的混合

不能小於12位,且必須為字母和數字的混合

/^(([a-z]+[0-9]+)|([0-9]+[a-z]+))[a-z0-9]*$/i

2.26 將阿拉伯數字替換為中文大寫形式

function replaceReg(reg,str){
  let arr=["零","壹","貳","叄","肆","伍","陸","柒","捌","玖"];
  let reg = /\d/g;
  return str.replace(reg,function(m){return arr[m];})
}

2.27 去掉標籤的所有屬性

<td style="width: 23px; height: 26px;" align="left">***</td>
變成沒有任何屬性的
<td>***</td>

思路:非捕獲匹配屬性,捕獲匹配標籤,使用捕獲結果替換掉字串。正則如下:

/(<td)\s(?:\s*\w*?\s*=\s*".+?")*?\s*?(>)/

2.28 駝峰表示

String.prototype.camelCase = function () {
        // .*?是非貪婪的匹配,點可以匹配任意字元,星號是前邊的字元有0-n個均匹配,問號是則是0-1;
        // (^\w{1}): 用於匹配第一個首字母
        // (.*):用於匹配任意個的前面的字元,.表示的就是任意字元

        // - param 1: 匹配到的字串
        // - param 2: 匹配的的子字串
        // - param 3: 匹配的子字串
        // - param的位置
        // - param 5: 原始字串 4: 匹配到的字串在字串中

        return this.replace(/(^\w{1})(.*)/g, function (match, g1, g2) {
            return g1.toUpperCase() + g2.toLowerCase();
        });
    }

2.29 模板字串

// str = 'name: @(name), age:@(age)'
       // data = {name : 'xiugang', age : 18}
       /**
        * 實現一個簡單的資料繫結
        * @param str
        * @param data
        * @return {*}
        */
       String.prototype.formateString = function (data) {
           return this.replace(/@\((\w+)\)/g, function (match, key) {
               // 注意這裡找到的值必須返回出去(如果是undefined,就是沒有資料)
               // 注意:判斷一個值的型別是不是undefined,可以通過typeof判斷
               console.log(typeof data[key] === 'undefined');
               return data[key] === 'undefined' ? '' : data[key];
           });

       }

2.30 去掉兩邊的空格

/**
        * 去掉兩邊的空格
        * @param str
        * @return {*}
        */
       String.prototype.trim = function () {
           return this.replace(/(^\s*)|(\s*$)/g, '');
       }

2.31 獲取url引數: 使用replace儲存到一個數組裡面,然後從數組裡面取出資料

'http://www.189dg.com/ajax/sms_query.ashx?undefined&undefined&undefined-06-27&undefined-06-27'
 url.replace(/(\w+)=(\w+)/g, function(a, b, c){
   console.log(a, b, c)
 })
action=smsdetail action smsdetail
sid=22 sid 22
stime=2014 stime 2014
etime=2014 etime 2014


// 封裝為一個函式
var url = "http://127.0.0.1/e/action/ShowInfo.php?classid=9&id=2";
function parse_url(_url){
 var pattern = /(\w+)=(\w+)/ig;
 var parames = {};
 url.replace(pattern, function(a, b, c){
   parames[b] = c;
 });
 return parames;
}
var parames = parse_url(url);
alert(parames['classid'] + ", " + parames['id']);