年糕很長,就快要吃完了
Regex 的運作:
從文本的 第一個字元前的位置
到 最後一個字元後的位置
一個一個去和 Pattern 做比對
直到 找到匹配的字元
或是 已經搜尋到最後一個字元
才會停止!
利用 ^
$
符號作為錨點
^
: 代表文本的開頭$
: 代表文本的結束
例如:
let str = 'Fake it till you make it';
alert(/^Fake/.test(str)); // true
// Fake 在整段文本的開頭 --> 印出 true
當 Regex Engine
遇到 \b
,它會檢查目前所在位置是否為單詞邊界
例如:
alert( "Hello, Java!".match(/\bJava\b/) ); // Java
alert( "Hello, JavaScript!".match(/\bJava\b/) ); // null
Hello, Java!
這段文本中,只有四個位置是單詞邊界
H
前o
後J
前a
後 (Java 第二個 a)Regex
有許多特殊的字元,像是 [ ] { } ( ) \ ^ $ . | ? * +
假設要搜尋的對象是這些特殊字元,需要在前面加上 \
例如:
alert( "Chapter 5.1".match(/\d\.\d/) ); // 5.1 (match!)
alert( "/".match(/\//) ); // '/'
Regex Engine
對於文本中每一個位置,都會重新去試著匹配所給的pattern
,如果沒有,就轉移到下一個位置Regex Engine
會一個位置一個位置往後推移檢查
例如:
let regexp = /".+"/g;
let str = 'a "witch" and her "broom" is one';
alert( str.match(regexp) ); // "witch" and her "broom"
// ".+" 這個 pattern 中第一個字元是 "
// 檢查到字母 a 不匹配 --> 往後找 --> 空格不匹配 --> 往後找 --> 在位置3的地方找到 "
// 引號找到了,Regex Engine 會接著往文本的後方看,看是否符合 .+
// . 代表任意字元,換行除外,所以 w 字母符合
// 因為有加量詞 + (一次以上),所以後面的字元都符合
// 直到... 文本結束的位置
這樣出現的問題是.+
會不斷地去 match 下一個位置的字元,直到文本結束。但都已經到文本的最後,也就不可能找到 "
Regex Engine
知道這點,所以會進行回溯 (倒退一格)
於是 .+
本來會比對到 one 的 e
--> 倒退一個位置,只比對到 n
--> e 則讓給 pattern 中的 "
e 和 "
不匹配,所以 Regex Engine
又再倒退一格
持續回溯倒退,直到找到 "
可匹配
Regex Engine
預設是採用這樣的貪婪模式,數量越多越好 挑戰極限
和上述的 Greedy mode
相反,數量盡可能找到越少越好
在量詞後面加上 ?
,就可以啟用 Lazy mode
,像是 *?
+?
??
例如:
let regexp = /".+?"/g;
let str = 'a "witch" and her "broom" is one';
alert( str.match(regexp) ); // "witch", "broom"
// 一樣在第三個位置找到 "
// 接著試著往後找字元可和 . 匹配
因為使用了 .?
懶惰模式,所以一但找到一個符合 .
的字元,下一個文本位置就會和剩餘的 pattern 進行比對
例如:
pattern "
和文本中的 i
做比對 --> 不匹配 --> i
歸給 .
--> 往後一個位置
pattern "
和文本中的 t
做比對 --> 不匹配 --> .... --> 持續往後找
以上圖皆取自 Greedy and lazy quantifiers
吸引力法則,每次複習完 Regex
都會在莫名的不久後,相遇它 (?)
: 表單需要驗證各個欄位
: 沒問題
: 這段文字可以幫我只取中間這段嗎
: 沒問題
: 可以幫我看看這段 Regex 寫錯在哪嗎
: 沒問題