<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【正則】954- 正則表達(dá)式有幾種字符匹配模式?

          共 6072字,需瀏覽 13分鐘

           ·

          2021-05-11 10:46


          最近再一次重溫老姚大佬的《JavaScript 正則表達(dá)式迷你書》 , 并將核心知識點整理一遍,方便復(fù)習(xí)。

          原書寫得非常棒,建議看下原書啦。  地址:https://github.com/qdlaoyao/js-regex-mini-book

          原書這么一句話,特別棒:正則表達(dá)式是匹配模式,要么匹配字符,要么匹配位置,要記住。

          1. 兩種模糊匹配

          正則表達(dá)式的強大在于它的模糊匹配,這里介紹兩個方向上的“模糊”:橫向模糊和縱向模糊。

          • 橫向模糊匹配

          即一個正則可匹配的字符串長度不固定,可以是多種情況。

          /ab{2,5}c/ 表示匹配:第一個字符是 "a" ,然后是 2 - 5 個字符 "b" ,最后是字符 "c"

          let r = /ab{2,5}c/g;
          let s = "abc abbc abbbc abbbbbbc";
          s.match(r); // ["abbc", "abbbc"]
          • 縱向模糊匹配

          即一個正則可匹配某個不確定的字符,可以有多種可能。

          /[abc]/ 表示匹配 "a", "b", "c" 中任意一個。

          let r = /a[123]b/g;
          let s = "a0b a1b a4b";
          s.match(r); // ["a1b"]

          2. 字符組

          • 范圍表示法

          可以指定字符范圍,比如 [1234abcdUVWXYZ] 就可以表示成 [1-4a-dU-Z] ,使用 - 來進(jìn)行縮寫。

          如果要匹配 "a", "-", "z" 中任意一個字符,可以這么寫:[-az][a\-z][az-] 。

          • 排除字符組

          即需要排除某些字符時使用,通過在字符組第一個使用 ^ 來表示取反,如 [^abc] 就表示匹配除了 "a", "b", "c" 的任意一個字符。

          • 常見簡寫形式
          字符組具體含義
          \d表示 [0-9],表示一位數(shù)字。
          \D表示 [^0-9],表示除數(shù)字外的任意字符。
          \w表示 [0-9a-zA-Z_],表示數(shù)字、大小寫字母和下劃線。
          \W表示 [^0-9a-zA-Z_],表示非單詞字符。
          \s表示 [\t\v\n\r\f],表示空白符,包含空格、水平制表符、垂直制表符、換行符、回車符、換頁符。
          \S表示 [^\t\v\n\r\f],表示非空白字符。
          .表示 [^\n\r\u2028\u2029] 。通配符,表示幾乎任意字符。換行符、回車符、行分隔符和段分隔符除外。

          然后表示任意字符,就可以使用 [\d\D]、[\w\W]、[\s\S][^] 任意一個。

          3. 量詞

          量詞也稱重復(fù),常用簡寫如下:

          量詞具體含義
          {m,}表示至少出現(xiàn) m 次。
          {m}等價于 {m, m} ,表示出現(xiàn) m 次。
          ?等價于 {0, 1} ,表示出現(xiàn)或不出現(xiàn)。
          +等價于 {1, } ,表示至少出現(xiàn)1次。
          *等價于 {0, } ,表示出現(xiàn)任意次,也有可能不出現(xiàn)。
          • 貪婪匹配和惰性匹配

          在正則 /\d{2,4}/ ,表示數(shù)字連續(xù)出現(xiàn) 2 - 4 次,可以匹配到 2 位、 3 位、4 位連續(xù)數(shù)字。

          但是在 貪婪匹配/\d{2,4}/g ,會盡可能多匹配,如超過 4 個,就只匹配 4 個,如有 3 個,就匹配 3 位。

          而在 惰性匹配/\d{2,4}?/g ,會 盡可能少 匹配,如超過 2 個,就只匹配 2 個,不會繼續(xù)匹配下去。

          let r1 = /\d{2,4}/g;
          let r2 = /\d{2,4}?/g;
          let s  = "123 1234 12345"
          s.match(r1); // ["123", "1234", "1234"]
          s.match(r2); // ["12", "12", "34", "12", "34"]
          惰性量詞貪婪量詞
          {m,m}?{m,m}
          {m,}?{m,}
          ???
          +?+
          *?*

          4. 多選分支

          即提供多個子匹配模式任選一個,使用 |(管道符)分隔,由于分支結(jié)構(gòu)也是惰性,即匹配上一個后,就不會繼續(xù)匹配后續(xù)的。

          格式如:(r1|r2|r3),我們就可以使用 /leo|pingan/ 來匹配 "leo""pingan"。

          let r = /leo|pingan/g;
          let s = "leo cool,pingan good.";
          s.match(r);// ["leo", "pingan"]

          // 多選分支的惰性表現(xiàn)
          let r1 = /leo|leooo/g;
          let r2 = /leooo|leo/g;
          let s  = "leooo";
          s.match(r1);// ["leo"]
          s.match(r2);// ["leooo"]

          5. 分組命名 (ES9)

          ES9 之前的分組是通過數(shù)字命名的:

          const pattern = /(\d{4})-(\d{2})-(\d{2})/u;
          const result = pattern.exec('2020-01-05');
          console.log(result[0]); // 打印"2020-01-05"
          console.log(result[1]); // 打印"2020"
          console.log(result[2]); // 打印"01"
          console.log(result[3]); // 打印"05"

          現(xiàn)在可以通過指定分組的名稱,增加代碼可讀性,便于維護(hù):

          const pattern = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u;
          const result = pattern.exec('2020-01-05');
          console.log(result.groups.year);         // 打印"2020-01-05"
          console.log(result.groups.month);        // 打印"01"
          console.log(result.groups.day);          // 打印"05"

          分組命名還可以和 String.prototype.replace 方法結(jié)合:

          const reDate = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
          const d = '2020-01-05';
          const USADate = d.replace(reDate, '$<month>-$<day>-$<year>');
          console.log(USADate);                        // 01-05-2020

          6. 忽略分組

          如果不希望捕獲某些分組,在分組內(nèi)加上 ?: 即可。比如 (?:tom).(ok) 那么這里 $1 指的就是 ok。

          7. 案例分析

          匹配字符,無非就是字符組、量詞和分支結(jié)構(gòu)的組合使用。

          • 十六進(jìn)制顏色值匹配
          let r = /#[0-9a-fA-F]{6}|#[0-9a-fA-F]{3}/g;
          let s = "#ffaacc #Ff00DD #fFF #01d #9Gd";
          s.match(r); // ["#ffaacc", "#Ff00DD", "#fFF", "#01d"]
          • 時間和日期匹配
          // 時間 12:23 或 01:09
          let r = /^([01][0-9]|[2][0-3]):[0-5][0-9]$/;  
          r.test("23:25"); // true
          r.test("03:05"); // true

          // 時間 12:23 或 1:9
          let r = /^(0?[0-9]|1[0-9]|[2][0-3]):(0?[0-9]|[1-5][0-9])$/;  
          r.test("23:25"); // true
          r.test("03:05"); // true
          r.test("3:5");   // true

          // 日期 yyyy-mm-dd
          let r = /^[0-9]{4}-(0[1-9]|[1][0-2])-(0[1-9]|[12][0-9]|3[01])$/;
          r.test("2019-09-19"); // true
          r.test("2019-09-32"); // false
          • Windows操作系統(tǒng)文件路徑匹配

          盤符使用 [a-zA-Z]:\\ ,這里需要注意 \ 字符需要轉(zhuǎn)義,并且盤符不區(qū)分大小寫;
          文件名或文件夾名,不能包含特殊字符,使用 [^\\:*<>|"?\r\n/] 表示合法字符;
          并且至少有一個字符,還有可以出現(xiàn)任意次,就可以使用 ([^\\:*<>|"?\r\n/]+\\)* 匹配任意個 文件夾\;
          還有路徑最后一部分可以是 文件夾 ,即沒有 \ 于是表示成 ([^\\:*<>|"?\r\n/]+)?

          let r = /^[a-zA-Z]:\\([^\\:*<>|"?\r\n/]+\\)*([^\\:*<>|"?\r\n/]+)?$/;
          r.test("C:\\document\\leo\\a.png"); // true
          r.test("C:\\document\\leo\\");      // true
          r.test("C:\\document");             // true
          r.test("C:\\");                     // true
          • id匹配

          如提取 <div id="leo" class="good"></id> 中的 id="leo"

          let r1 = /id=".*"/;    // tips1
          let r2 = /id=".*?"/;   // tips2
          let r3 = /id="[^"]*"/// tips3

          let s  = '<div id="leo" class="good"></id>';
          s.match(r1)[0];  // id="leo" class="good"
          s.match(r2)[0];  // id="leo"
          s.match(r3)[0];  // id="leo"

          tips1:由于 . 匹配雙引號,且 * 貪婪,就會持續(xù)匹配到最后一個雙引號結(jié)束。
          tips2:使用惰性匹配,但效率低,有回溯問題。
          tips3:最終優(yōu)化。

          1. JavaScript 重溫系列(22篇全)
          2. ECMAScript 重溫系列(10篇全)
          3. JavaScript設(shè)計模式 重溫系列(9篇全)
          4. 正則 / 框架 / 算法等 重溫系列(16篇全)
          5. Webpack4 入門(上)|| Webpack4 入門(下)
          6. MobX 入門(上) ||  MobX 入門(下)
          7. 120+篇原創(chuàng)系列匯總

          回復(fù)“加群”與大佬們一起交流學(xué)習(xí)~

          點擊“閱讀原文”查看 120+ 篇原創(chuàng)文章

          瀏覽 58
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  天天爽夜夜爽精品成人免费 | 午夜影院无码 | 亚洲淫秽视频在线 | 天天躁日日躁狠狠躁免费麻豆 | 日本韩国欧美 |