問題一、什麼是正規表達式?
問題二、RegExp 和regex差別在哪裡?
RegExp 和 regex 是不同的。
RegExp 是JavaScript中的一个内置對象,表示正規表達式。可以使用 RegExp
構造函數来創建正規表達式對象。例如:
const regex = new RegExp('模式', '標誌');
regex 是通用的變數名,用來保存正規表達式对象。例如:
const regex = /pattern/flags;
分別以regex當作變數,分別使用 literal notation 和constructor 寫法:
const regex = /ab+c/i; // literal notation
// OR
const regex = new RegExp("ab+c", "i"); // constructor with string pattern as first argument
// OR
const regex = new RegExp(/ab+c/, "i"); // constructor with regular expression literal as first argument
問題三、RegExp的兩種表達方式, literal notation和constructor是什麼?
以下程式碼分別將表達 literal notation和constructor:
const re = /ab+c/i; // literal notation 字面範本值表達,i 表示不區分大小寫的匹配。
const re = new RegExp("ab+c", "i"); 構造函數表達正規表達式,第一個參數用字串表達
// constructor with string pattern as first argument
const re = new RegExp(/ab+c/, "i"); 構造函數表達正規表達式,第一個參數用正規表達式表達
// constructor with regular expression literal as first argument
使用構造函數時,需要遵循正常的字符串轉義規則(即在字符串中包含特殊字符時需要在符號的前面加上\
),也就是斜線\
前面的特殊字符,不會被以正規表達式特殊字符看待,而是以字串看待。
以下這兩個是相等的。
const re = /\w+/;
const re = new RegExp("\\w+");
註解:\
w 在正規表達式中,意思為匹配大小寫文字letters (A–Z, a–z), 數字numbers (0–9), 和下底線underscore (__
).
// 使用字面值表示法創建一個正則表達式,匹配數字字符
const regexLiteral = /\d+/;
// 使用正則表達式進行匹配
const resultLiteral = regexLiteral.exec("12345");
console.log(resultLiteral);
// 輸出: [ '12345', index: 0, input: '12345', groups: undefined ]
// 使用RegExp構造函數創建一個正則表達式,匹配由變數決定的模式
const pattern = "\\d+"; // 匹配一個或多個數字字符的模式
const regexConstructor = new RegExp(pattern);
// 使用正則表達式進行匹配
const resultConstructor = regexConstructor.exec("12345");
console.log(resultConstructor); // 輸出: [ '12345', index: 0, input: '12345', groups: undefined ]
字面範本值在代碼解析期間編譯正則表達式,而RegExp構造函數允許在運行時編譯,並且可以根據變數值或運行時邏輯動態生成模式。有時候使用字面範本值 比構造函數效能高。
問題四、正規表達式有哪些?
\W
\W 不匹配: 數字,和字母(或混雜),和下底線。其他可以匹配
/judy7778999\W/.test("judy7778999**"); //true
\w
\w 匹配大小寫文字(A–Z, a–z), 數字(0–9), 和下底線(`__`)
/judy7778999\w/.test("judy7778999abcdA123_"); //true
\D
\D 只要不是數字,匹配大小寫字母、符號等等
/judy7778999\D/.test("judy7778999AAAAA"); //true
\d
\d 匹配任何數字,0-9
/\djudy7778999\D/.test("123judy7778999AAAAA"); //true
\S
\S 匹配任何不是空格的字母、數字、符號
/\Sjudy/.test("1234ABCjudy"); //true
\s
\s 匹配任何空格
/\sjudy/.test(" judy"); //true
/\sjudy/.test("judy"); //false 因為judy前面沒有空格
. 任何文字、字母、數字、符號都可以
/judy\./.test("judy123"); //false 因為.前面不用加上反斜線
/../.test("😄"); // true; matches two UTF-16 code units as a surrogate pair
/../u.test("😄"); // false; input only has one Unicode character
\.
跳脫字元 這部分在書中3.3.2有提到"\.judy\."; //.judy.
"\'judy\'"; //"'judy'" 雙引號內再加一組單引號
"\/judy\/"; // '/judy/'
"\\judy\\"; // '\\judy\\'
[]
[] 中括號裡面的數字或文字才允許
/[1]/.test("1"); //true
/[1]/.test("123"); //true 只有1是相同的也匹配
[]
也可以這樣寫註解: 以直列來看,T,H,B 一組、o, i, i一組、p, l, r一組、d自己一組
const a = ["Top", "Hill", "Bird" ];
/[B-T][i-o][i-r][d]/.test(a); //true
寫成if else:
if(/[B-T][i-o][i-r][d]/.test(a)){
console.log("Correct")
}else{
console.log("Incorrect")
}
// Correct
[^abc]
匹配不包含a, b, c (三者皆不可以包含)/[^123]/.test("456"); //true
? 可以完全沒有,也可以有很多個 //quantifier 是指min:0 max:1
const pattern3 = /c?/;
console.log(text.match(pattern3)); // [""]
/happy1234567a?b?/.test("happy1234567acccbccccvvvbbb"); //true
/happy1234567a?b?/.test("happy1234567"); //true
+ 一個或是更多個
+:匹配 b 1 次或多次 //quantifier+ 是指min:1 max:infinity(無限大)
const pattern2 = /b+/;
console.log(text.match(pattern2)); // ["bbbb"]
/happy123456+/.test('happy1234566'); //true 6後面有加了數字6
/happy123456+/.test('happy1234566');
//true 6後面就算沒加,因為原本就有一個6了,所以符合+的條件(一個以上)
// {n,}:匹配 b 至少 2 次 //quantifier{n,} min:2 max:infinity
const pattern5 = /b{2,}/;
console.log(text.match(pattern5)); // ["bbbb"]
{m,n} {}前面字母重複次數的範圍
// {n,m}:匹配 c 1 到 3 次 //quantifier{min, max} min:1 max:3
const pattern6 = /c{1,3}/;
console.log(text.match(pattern6)); // ["ccc"]
const b = ["happppppy", "happy"];
/hap{2,3}y/.test(b); //true
*
const text = "aaaaabbbbcccc";
// *:匹配 a 0 次或多次 //quantifier* 是指min:0 max:infinity(無限大)
const pattern1 = /a*/;
console.log(text.match(pattern1)); // ["aaaaa"]
const c = ["abc", "abbbbc", "aabbccccc"]; 匹配0次到多次都可以
/a*b*c*/.test(c); //true
問題五、RegExp輸出的方式有哪些?
"happy12345678".match(/1234/);
//結果: ['1234', index: 5, input: 'happy12345678', groups: undefined]
"happy12345678".match(/1234566/);
//結果: null
/happy12345678a*b*/.test("happy12345678aabb"); //true
//正規表達式中,a* 代表a後面可以放大於1個a的字母、大於1個的b字母
/happy12345678a*b*/.test("happy12345678a11b22"); //true
//數字也可以放
/happy12345678/.test("1234567"); // false
未完待續~~~
Reference
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/RegExp
練習regex網站 : https://regexone.com/