正則表達式詳解及實戰

正則表達式

Create by jsliang on 2018-11-14 10:41:20
Recently revised in 2018-11-19 08:46:37


Hello 小夥伴們,如果覺得本文還不錯,記得給個 star,你們的 star 是我學習的動力!GitHub 地址


 正則表達式:正則,也叫做規則,讓計算機能夠讀懂人類的規則。
 正則表達式是繁瑣的,越學你會覺得越發發狂。
 但是,它又是強大的。正則在我眼裏,就是作弊碼,學會之後的應用可以大大提高你的開發效率。
 所以,你可以老老實實打怪,但是你用了它會覺得編程更爽快。

 綜上,有了 jsliang 編寫這篇文章來記錄自己所學的衝動。
 爲此,也是靈感觸發,jsliang 寫了個 PC 小遊戲(請用電腦打開網址):

GIF圖無法上傳,點擊上面的遊戲地址直接查看吧~


一 目錄


不折騰的前端,和鹹魚有什麼區別~

目錄
一 目錄
二 整合
2.1 常用正則
2.2 匹配規則
2.3 常用方法
三 正則旅途
3.1 初識正則
3.2 正則解析
3.3 正則練習
3.4 漸入佳境:() 匹配子項
 [3.5 漸入佳境:[] 字符類](#chapter-three-five)
四 回顧總結


二 整合

目錄


 本章節整理總結了所有的參考文獻,方便日後快速回顧回憶。
 如果你還沒正式開始正則表達式,請快速瀏覽跳過本章節。

 精選參考文獻/視頻/手冊:


2.1 常用正則表達式

目錄


  1. 驗證姓名
  • 2 到 9 位中文暱稱:^[\u4e00-\u9fa5]{2,9}$
  1. 驗證密碼
  • 只能是字母、數字和下劃線,長度不限制: ^\w+$
  • 允許 小寫字母 a-z、大寫字母 A-Z、數字 0-9、下劃線 _、 連接符 -,且長度在 6-18 位數: /^[a-zA-Z0-9_-]{6,18}$/
  • 必須包含數字+小寫字母+大寫字母的密碼,且長度在8-10位之間: ^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$
  1. 驗證 Email
  • 允許有一個字符符合 [A-Za-z0-9_] 之後可以爲 [A-Za-z0-9_-+.] + @ + 允許有一個字符符合 [A-Za-z0-9_] 之後可以爲 [A-Za-z0-9_-.] + . + 允許有一個字符符合 [A-Za-z0-9_] 之後可以有 [A-Za-z0-9_-.] 的郵箱: ^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
  1. 驗證身份證
  • 18 位身份證號,尾數是數字或者字母 X: ^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)$
  • 15 或者 18 位身份證號,尾數可以是數字及 X 或者 x: (^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)
  1. 驗證手機號
  • 以 1 開頭,第二位數是 3/4/5/7/8 的 11 位手機號碼: ^1[3,4,5,7,8,9]\d{9}$
  • 移動號碼: ^134[0-8]\d{7}$|^(?:13[5-9]|147|15[0-27-9]|178|1703|1705|1706|18[2-478])\d{7,8}$
  • 電信號碼: ^(?:133|153|1700|1701|1702|177|173|18[019])\d{7,8}$
  • 聯通號碼: ^(?:13[0-2]|145|15[56]|176|1704|1707|1708|1709|171|18[56])\d{7,8}|$


2.2 匹配規則

目錄


字符 描述 例子
\ 將下一個字符標記爲特殊字符、或原義字符、或向後引用、或八進制轉義符。 \n 表示換行符、\d 匹配 [0-9] 的數字
^ 匹配輸入字符串的開始位置。 ^abc 表示匹配有 abc 開頭的字符串
$ 匹配輸入字符串的結束位置。 ^\d$ 表示匹配一個 [0-9] 的數字
* 匹配前面的子表達式零次或多次。 zo* 能匹配 z 或者 zoo* 等價於 {0,}
+ 匹配前面的子表達式一次或多次。 zo+ 能匹配 zo 或者 zoo,但不能匹配 z+ 等價於 {1,}
? 匹配前面的子表達式零次或一次。 do(es)? 可以匹配 doesdoes 中的 do? 等價於 {0,1}
{n} n 是一個非負整數。匹配確定的 n 次。 o{2} 不能匹配 Bob 中的 o,但是能匹配 food 中的兩個 o
{n,} n 是一個非負整數。至少匹配 n 次。 o{2,} 不能匹配 Bob 中的 o,但能匹配 foooood 中的所有 oo{1,} 等價於 o+o{0,} 則等價於 o*
{n,m} m 和 n 均爲非負整數,其中 n <= m。最少匹配 n 次且最多匹配 m 次。 例如,o{1,3} 將匹配 fooooood 中的前三個 o。o{0,1} 等價於 o?。請注意在逗號和兩個數之間不能有空格。
? 當該字符緊跟在任何一個其他限制符 *+?{n}{n,}{n,m} 後面時(例如 +?),匹配模式是非貪婪的。非貪婪模式儘可能少的匹配所搜索的字符串,而默認的貪婪模式則儘可能多的匹配所搜索的字符串。 對於字符串 ooooo+? 將匹配單個 o,而 o+ 將匹配所有 o
. 匹配除 \n 之外的任何單個字符。. 是一個很強大的 元符號,請慎用。 要匹配包括 \n 在內的任何字符,請使用 `(. n) 的模式。要匹配小數點本身,請使用 .a.e 能匹配 nave 中的 ave 或者匹配 water 中的 ate`
(子表達式) 標記一個子表達式的開始和結束位置。 (\w)\1 能匹配 deep 中的 ee
(?:子表達式) 匹配 z子表達式 但不獲取匹配結果,也就是說這是一個非獲取匹配,不進行存儲供以後使用。這在使用或字符 `( )` 來組合一個模式的各個部分是很有用。 `industr(?:y ies) 就是一個等同於 industry industries` 但更簡略的正則表達式。
(?=子表達式) 一般用法:××(?=子表達式),它的意思就是 ×× 後面的條件限制是 ?= 後面的 子表達式 `Windows(?=95 98 NT 2000) 能匹配 Windows2000 中的 Windows,但不能匹配 Windows3.1 中的 Windowsw+(?=.) 能匹配 He is. The dog ran. The sun is out. 中的 isranout`
(?!子表達式) 類似於 (?=子表達式),表示不等於後面的 子表達式 `Windows(?!95 98 NT 2000) 能匹配 Windows3.1 中的 Windows,但不能匹配 Windows2000 中的 Windowsb(?!un)w+b 能匹配 unsure sure unity used 中的 sureused`
(?<=子表達式) 同上。 `(?<=95 98 NT 2000)Windows 能匹配 2000Windows 中的 Windows,但不能匹配 3.1Windows 中的Windows(?<=19)d{2}b 能匹配 1851 1999 1950 1905 2003 中的 995005`
(?<!子表達式) 同上。 `(?<!95 98 NT 2000)Windows 能匹配 3.1Windows 中的 Windows,但不能匹配 2000Windows 中的 Windowsb(?!un)w+b 能匹配 unsure sure unity used 中的 sureused`
`x y` 匹配 x 或者 y。 `z food 能匹配 z 或者 food(z f)ood 則匹配 zoodfood`。
[xyz] 字符集合。匹配所包含的任意一個字符。 [abc] 可以匹配 plain 中的 a
[^xyz] 求反。匹配未包含的任意字符。 例如,[^abc] 可以匹配 plain 中的 p[^aei] 匹配 reign 中的 rgn
[a-z] 字符範圍。匹配指定範圍內的任意字符。 [a-z] 可以匹配 az 範圍內的任意小寫字母字符。注意:[A-Z] 才匹配大寫英文字母
[^a-z] 求反。匹配任何不在指定範圍內的任意字符。 [^a-z] 可以匹配任何不在 az 範圍內的任意字符。
\b 匹配一個單詞邊界,也就是指單詞和空格間的位置。 er\b 可以匹配 never 中的 er,但不能匹配 verb 中的 er
\B 匹配非單詞邊界。 er\B 能匹配 verb 中的 er,但不能匹配 never 中的 er
\cx 匹配由 x 指明的控制字符。 例如,\cM 匹配一個 Control-M 或者回車符。x 的值必須爲 A-Za-z 之一。否則,將 c 視爲一個原義的 c 字符。
\d 匹配一個數字字符。等價於[0-9]。 4 = IV 中的 4
\D 匹配一個非數字字符。等價於1 4 = IV 中的 = IV
\f 匹配一個換頁符。等價於x0c和cL。 [\f]{2,} 能匹配 \f\f\f 中的 \f\f\f
\n 匹配一個換行符。等價於x0a和cJ。 \r\n(\w+) 能匹配 \r\nThese are\ntwo lines. 中的 \r\nThese
\r 匹配一個回車符。等價於x0d和cM。 \r\n(\w+) 能匹配 \r\nThese are\ntwo lines. 中的 \r\nThese
\s 匹配任何空白字符,包括空格、製表符、換頁符等等。等價於[ fnrtv]。 \w\s 能匹配 ID A1.3 中的 D
\S 匹配任何非空白字符。等價於2 \s\S 能匹配 int __ctr 中的 _
\t 匹配一個製表符。等價於x09和cI。 (\w+)\t 能 匹配 item1\titem2\t 中的 item1\titem2\t
\v 匹配一個垂直製表符。等價於x0b和cK。 [\v]{2,} 能匹配 \v\v\v 中的 \v\v\v
\w 匹配包括下劃線的任何單詞字符。等價於 [A-Za-z0-9_] ID A1.3 中的 IDA13
\W 匹配任何非單詞字符。等價於 [^A-Za-z0-9_] ID A1.3 中的 .


2.3 常用方法

目錄


 JavaScript 正則默認: 正則匹配成功就會結束,不會繼續匹配。如果想查找全部,就要加標識 g(全局匹配)


  1. test()

規則:正則表達式搜索字符串指定的值,從而去匹配字符串。如果匹配成功就返回 true,如果匹配失敗就返回 false
用法正則.test(字符串)
案例

js 代碼片段
var str = "123abc";
var re = /\D/; // 匹配非數字
if(re.test(str)) {
  console.log("不全是數字!");
} else {
  console.log("全是數字!");
}
Console:不全是數字


  1. search()

規則:正則去匹配字符串,如果匹配成功,就返回匹配成功的位置,如果匹配失敗就返回 -1
用法字符串.search(正則)
案例

js 代碼片段
var str = "abcdef";
var re1 = /d/i; // 3
var re2 = /h/i; // -1
console.log(str.search(re1));
console.log(str.search(re2));
Console:
3
-1


  1. match()

規則:正則去匹配字符串,如果匹配成功,就返回匹配成功的數組,如果匹配不成,就返回 null
用法字符串.match(正則)
案例

js 代碼片段
var str = "123fadf321dfadf4fadf1"; //(4) ["123", "321", "4", "1"]
var re = /\d+/g;
console.log(str.match(re));
Console:(4) ["123", "321", "4", "1"]


  1. replace()

規則:正則去匹配字符串,匹配成功的字符串去替換成新的字符串。函數的第一個參數,是匹配成功的字符;第二個參數:可以是字符串,也可以是一個回調函數。
用法字符串.replace(正則,新的字符串)
案例

  • 簡單案例
js 代碼片段
var str = 'aaa';
var re = /a+/g;
str = str.replace(re, "b");
console.log(str); // b
Console:b


  • 敏感詞過濾
html 代碼片段
<div class="filtering-of-sensitive-words">
  <h3>敏感詞過濾</h3>
  <p>替換前</p>
  <textarea name="before" id="" cols="30" rows="10"></textarea>
  <input type="button" value="確定" id="input1">
  <p>替換後</p>
  <textarea name="after" id="" cols="30" rows="10"></textarea>
</div>
js 代碼片段
window.onload = function() {
  var aT = document.getElementsByTagName("textarea");
  var oInput = document.getElementById("input1");

  var re = /非誠|中國船|監視之下/g;

  oInput.onclick = function() {
    // 一律單個替換: aT[1].value = at[0].value.replace(re, "*");
    // 多個替換:
    aT[1].value = aT[0].value.replace(re, function(str) {
      var result = "";
      for(var i=0; i<str.length; i++) {
        result += "*";
      }
      return result;
    });
  }
}
Console
替換前:非誠勿擾在中國船的監視之下寸步難行
替換後:**勿擾在***的****寸步難行


三 正則旅途

目錄


 什麼是正則表達式?正則表達式:正則,也叫做規則,讓計算機能夠讀懂人類的規則。
 正則表達式都是用來操作字符串的。

本文學習目標

  1. 通過小故事給小夥伴學習 JavaScript 的正則表達式
  2. 讓小夥伴能瞭解基本正則表達式的意思,並能自己寫正則表達式


3.1 初識正則

目錄


 正則長咋樣?怎麼用?很簡單,三行代碼帶你入門

var regex = /^\d+$/;
var myNumber = '123';
console.log(regex.test(myNumber)); // true

 上面的正則,能驗證字符串 myNumber 是不是純數字組成,就這麼簡單,正則入門了!
 但是,如果我要是敢就這麼結束文章,我敢保證你們想拍死我!所以,我們通過一個表達式的故事來初識正則表達式:

 某天,盜賊小白給了盜賊小黑一個盒子,盒子像俄羅斯套娃一樣,有 3 層嵌套:

圖片描述

 並且,他們約定了交易密碼提取方式:小白將給小黑提供一串字符串,小黑只需要將字符串中的所有相連的數字找出來,然後把它們拼接成一個新數組,數組的第一項就是第一個盒子的密碼,以此類推……

"abc123def456hash789" -> [123, 456, 789] - > [外層盒子1密碼, 中間層盒子2密碼, 最內層盒子3密碼]

 現在假設盜賊小黑使用 JavaScript 進行常規查找:

index.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>正則表達式</title>
</head>

<body>
  <p>正則表達式 | <b>jsliang</b> 學習記錄</p>

  <script>
    window.onload = function () {
      var str = "abc123def456hash789"

      function findNum(str) {
        var arr = [];
        var tmp = '';
        for (var i = 0; i < str.length; i++) {
          if (str.charAt(i) >= "0" && str.charAt(i) <= "9") {
            tmp += str.charAt(i);
          } else {
            if (tmp) {
              arr.push(tmp);
              tmp = "";
            }
          }
        }
        if (tmp) {
          arr.push(tmp);
          tmp = "";
        }
        return arr;
      }
      console.log(findNum(str));
    }
  </script>
</body>

</html>


 寫到這裏,小黑覺得不妥,上面代碼寫得太麻煩太複雜了,於是決定使用正則表達式查找:

index.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>正則表達式</title>
</head>

<body>
  <p>正則表達式 | <b>jsliang</b> 學習記錄</p>

  <script>
    window.onload = function() {
      var str = "abc123def456hash789";
      function findNum(str) {
        return str.match(/\d+/g);
      }
      console.log(findNum(str));
    }
  </script>
</body>

</html>


 小黑瞬間覺得自己很牛逼有木有?!只需要一行代碼,就能解決字符串查找的時候用的一大串代碼!

 那麼,講到這裏,小夥伴們應該對正則有了個簡單的瞭解,稱熱打鐵,Here we go~


3.2 正則解析

目錄


 在上文中,盜賊小黑通過使用 str.match(/\d+/g),解決了獲取箱子密碼的問題。
 那麼,這串正則表達式是什麼意思呢?我們先拋開這個,解析一串簡單的:

^[a-z0-9_-]{6,12}$

 首先,^ 表示匹配字符串的開始位置,結合後面的 [a-z0-9_-] 表示該字符串開頭可以爲 a-z 的字母,0-9 的數字,_ 下劃線,- 連接符。
 然後,[a-z] 表示匹配 a-z 中任意單個字母;[0-9] 表示匹配 0-9 中任意單個數字;[_] 表示匹配下劃線;[-] 表示匹配連接符 -。所以,將前面的連起來,[a-z0-9_-] 表示字符串可以包含數字字母_- 這四種形式的字符串。
 接着,{6, 12} 表示該字符串的長度爲 6-12 位。
 最後,$ 表示結束標誌,^ 的相反。

^$ 同時使用時,表示精確匹配。

 終上所述,小夥伴們應該猜測到了這個正則表達式的用途:校驗用戶名。該用戶名只能包含字符、數字、下劃線 (_) 和連接字符 (-),並且用戶名的長度最長爲 12 位,最短爲 6 位。

 那麼,它在 JavaScript 中要如何使用呢?我們通常用 /正則表達式/ 兩個斜槓來包裹我們要寫的正則表達式:

var reg = /^[a-z0-9_-]{6,12}$/

 看,這樣就是一條規則了,如果你需要讓他匹配一個字符串 str。那麼,只需要在代碼中使用 test() 測試方法:

var str = 'abc-cba_abc';
var reg = /^[a-z0-9_-]{6,12}$/;
console.log(reg.test(str)); // true

 這樣,我們就告訴了 JavaScript:reg 通過 test() 方法去測試 str 是否符合 reg的規則,如果符合則返回 true,如果不符合則返回 true。這裏返回的是 true,因爲我們的 str 是符合 reg 規則的。

test() 方法及其他好用的方法已經整合到 【2.3 JS 正則方法】 裏面了,迫不及待的小夥伴們可點擊鏈接先行查看。

 下面貼出完整代碼:

index.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>正則表達式</title>
</head>

<body>
  <p>正則表達式 | <b>jsliang</b> 學習記錄</p>

  <script>
    window.onload = function() {
      var str = 'abc-cba_abc';
      var reg = /^[a-z0-9_-]{6,12}$/;
      console.log(reg.test(str)); // true
    }
  </script>
</body>

</html>


3.3 正則練習

目錄


 通過上面的瞭解,小夥伴對正則表達式應該有了初始的瞭解,下面我們猜測一下,下面的 Console 1 - Console 3中, 哪些是 true,哪些是 false

index.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>正則表達式</title>
</head>

<body>
  <p>正則表達式 | <b>jsliang</b> 學習記錄</p>

  <script>
    window.onload = function() {
      var str = "Cheer for yourself";
      var reg1 = /^Cheer/;
      var reg2 = /yourself$/;
      var reg3 = /for/;
      console.log(reg1.test(str));
      console.log(reg2.test(str));
      console.log(reg3.test(str));
    }
  </script>
</body>

</html>


 答案是,這三個都返回 true。在這三個 console.log() 中:
 第一個判斷該字符串是否以 Cheer 開頭;
 第二個判斷該字符串是否以 yourself 結尾;
 第三個判斷該字符串是否包含 for
 在日常工作中,經常利用該方法,判斷用戶輸入的 string 裏面是否包含某些文字,例如:jsliang 是傻逼,就需要判斷替換爲 jsliang 是帥哥,至於怎麼替換敏感字,迫不及待的小夥伴們可前往 【2.3 JS 正則方法】 先行了解~


3.4 漸入佳境:() 匹配子項

目錄


 所謂匹配子項,其實就是我們的小括號 () 。它還有另外一個意思,叫分組操作。下面我們引用章節 【2.2 正則表達式規則】 中的定義:

表達式 釋義 用法
(子表達式) 標記一個子表達式的開始和結束位置。 (\w)\1 能匹配 deep 中的 ee

 如果光解釋意思,小夥伴們可能稀裏糊塗。所以我們先上代碼:

js 代碼片段
var str = "2018-11-28";
var re = /(\d+)(-)/g;
str = str.replace(re, function($0, $1, $2){
  // 第一個參數:$0(母親)
  // 第二個參數:$1(第一個孩子)
  // 第三個參數:$2 (第二個孩子)
  console.log("$0:" + $0); // 2018- 以及 11-
  console.log("$1:" + $1); // 2018 以及 11
  console.log("$2:" + $2); // - 以及 -
  return $1 + '.';
});
console.log(str); // 2018.11.28
Console:
$0:2018-
$1:2018
$2:-
$0:11-
$1:11
$2:-
2018.11.28

首先,我們解析下這段正則:

  • /(\d+)/ 表示任意 1 個及以上的數字
  • /(-)/ 表示匹配字符 -
  • g 表示匹配一次以上

 所以這段正則的意思就是匹配一次及以上的 數字- 形式的字符串。
然後,我們使用了 replace() 方法。我們觀察 Console 打印出來的結果,可以看出:$0 即是我們的正則 var re = /(\d+)(-)/g 去匹配 var str = "2018-11-28" 所得到的結果,這裏我們匹配成功了兩次,即 2018-11-$1 即是我們的一個小括號 (\d+) 的匹配結果,所以結果爲 2018 以及 11$2 即是我們的第二個小括號 (-) 的匹配結果,所以結果爲 - 以及 -
最後,我們做的事情就是,將 $1 加上 .,並返回最終結果給 str,即最終結果:2018.11.28

在這裏提到了 replace() 方法,詳情可瞭解:點擊前往


【Once again】 如果小夥伴們感覺還是不過癮,那麼我們再來一段:

js 代碼片段
var str = "abc";
var re = /(a)(b)(c)/;
console.log(str.match(re));
Console
(4) ["abc", "a", "b", "c", index: 0, input: "abc", groups: undefined]

 這裏我們不做過多講述,相信小夥伴們經過這兩個案例,應該對 () 有了一定的瞭解。


3.5 漸入佳境:[] 字符類

目錄

 何爲字符類?
 所謂字符類,就是一組類似的元素 [] 這樣的中括號的整體,所代表一個字符。
 話不多說,先上代碼:

js 代碼片段
var str1 = "abcd";
var re1 = /a[bcd]c/;
console.log(re1.test(str1)); // true

var str2 = "abc";
var re2 = /a[^bcd]c/;
console.log(re2.test(str2)); // false

var str3 = "a.c";
var re3 = /a[a-z0-9A-Z]c/;
console.log(re3.test(str3));  // false
Console
true
false
false

首先,我們先解析第一部分:

  • /a/:匹配字母 a
  • /[bcd]/:匹配字母 bcd 中的一位
  • /[d]:匹配字母 d

 所以,可以看出,我們用 re1 來測試 str1 是否符合,它會返回 true

然後,我們解析第二部分:

  • ^ 如果寫在 [] 裏面的話,就代表排除的意思。在這裏就代表着 ac 中間不能是 bcd 中的任意一個

 所以,可以看出,我們用 re2 來測試 str1 是否符合,它會返回 false

最後,我們解析第三部分:

  • /[a-z0-9A-Z]/:匹配小寫字母 a-z,或者數字 0-9,或者大寫字母 A-Z。即 ac 之間只能是上面匹配地上的字符。

 所以,可以看出,我們用 re3 來測試 str3 是否符合,它會返回 false


四 回顧總結

目錄


 在第三章中,我們介紹了強大之處,介紹了它的使用方法,並通過小練習、() 以及 [] 的講解,讓小夥伴們更進一步瞭解在 JavaScript 中正則的使用……
 但!
 這是完結嗎?!
 不!
 由於 jsliang 時間有限,沒法一一給小夥伴們介紹正則的樂趣及工作中如何使用正則提高工作效率。
 所以,在第二章 【整合】 中,jsliang 整合網上資源,記錄了一些常用的正則工具,裏面有很多東西,是在這篇文章中沒有涉及的,有興趣的小夥伴可以逐一嘗試加深對正則的瞭解。

————For the end————
 在編寫這篇文章中,jsliang 玩性大發寫下了下面的遊戲(請用電腦查看):


如果小夥伴們覺得本文還不錯,記得 GitHub 點個 star, 你們的 star 是我學習的動力!GitHub 地址


<img alt="知識共享許可協議" style="border-width:0" src="https://i.creativecommons.org...; />
jsliang 的文檔庫樑峻榮 採用 知識共享 署名-非商業性使用-相同方式共享 4.0 國際 許可協議進行許可。
基於https://github.om/LiangJunron...上的作品創作。
本許可協議授權之外的使用權限可以從 https://creativecommons.org/l... 處獲得。

  1. 0-9
  2. fnrtv
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章