前言:能看到這篇隨筆的朋友肯定, 多多少少接觸過正則( 不過還記得多少, 只有"天"知道 ), 基礎語法知識我們先扔一邊, 先從實際程式設計入手去, 驗證瀏覽器中正則的四種常規操作: 驗證、切分、提取、替換
使用正則的目的就三個
- 表單校驗( 查詢字串中是否有匹配正則規則的字元 ) 如果滿足就 XX, 如果沒滿足就 OO
- 提取字串中的內容(分組) - 提取之後做後續操作(替換
replace
就是提取的後續操作)- 切分
split
1. 驗證
驗證:查詢字串中是否有匹配正則規則的字元。 先來一道基礎題
Demo1 判斷一個字串中是否包含"hello" ( 判斷字串中是否包含某個字串 )
String物件上的方法
方法一: indexOf()
let str = "hello world!";
console.log(str.indexOf("hello") != -1); // true
// 不是正則, 但卻是解決當前題的一種方案,
// indexOf()方法返回撥用String物件中第一次出現的指定值的索引, 如果未找到該值, 則返回-1
複製程式碼
方法二: includes()
let str = "hello world!";
console.log(str.includes("hello")); // true
// includes() 方法用於判斷一個字串是否包含在另一個字串中, 根據情況返回true或false
複製程式碼
方法三: search()
let str = "hello world!";
console.log(str.search(/hello/) != -1);
// 只有一個引數, 並且是一個正規表示式物件, 如果傳入一個非正規表示式物件,
// 則會使用 new RegExp(obj)隱式地將其轉換為正規表示式物件
// 如果匹配成功, 則返回正規表示式在字串中首次匹配項的索引, 否則, 返回-1
複製程式碼
方法四: match()
let str = "hello world!";
console.log(!!str.match(/hello/g));
// 如果傳入一個非正規表示式物件, 則會隱式地使用new RegExp(obj)將其轉換為一個RegExp
// 返回值(陣列), 如果匹配到陣列第一項是匹配的完整字串, 之後項是用圓括號捕獲的結果, 如果沒有匹配到, 返回null
// 如果正規表示式包含g標誌, 則該方法返回一個Array, 它包含所有匹配的子字串而不是匹配物件
複製程式碼
RegExp 物件上的方法
方法五: test()
let str = "hello world!";
console.log(/hello/.test(str));
// 用來檢視正規表示式與指定的字串是否匹配, 返回true或false
// 想要知道一個模式是否存在於一個字串中, 可以使用test()或者search
複製程式碼
方法六: exec()
let str = "hello world!";
console.log(!!/hello/.exec(str));
// exec() 方法在一個指定字串中執行一個搜尋匹配, 返回一個結果陣列或null,
// 如果只是為了判斷是否匹配(true或false), 可以使用RegExp.test()方法, 或者String.search()方法
複製程式碼
驗證總結:
- 一個確認的( 精準匹配 )字元查詢是否被包含, 使用
String.indexOf() 和 String.includes()
- 一個有規則的( 模糊匹配 )字元查詢是否被包含, 使用
RegExp.test() 和 String.search()
- 查詢不推薦, 使用
String.match() 和 RegExp.exec()
切分
切分:所謂"切分", 就是把目標字串, 切分成一塊一塊的, 在
JS
中使用split
Demo2 目標字串是"html,css,javascript", 按逗號切分
let regex = /,/;
let str = "html,css,javascript";
let str2 = "2018/10/18";
console.log(str.split(regex));
console.log(str2.split(/\//));
複製程式碼
split()
方法使用指定的分隔符字串將一個String
物件分割成字串陣列, 以將字串分隔為子字串, 以確認每個拆分的位置
分隔符可以是一個字串或正規表示式
提取
提取:很多時候需要提取部分匹配的資料, 通常需要使用分組引用( 分組捕獲 )
Demo3 提取年月日
方法一: match()
let str = "2018-10-18";
let regex = /^(\d{4})\D(\d{2})\D(\d{2})$/;
console.log(str.match(regex));
複製程式碼
方法二: exec()
let str = "2018-10-18";
let regex = /^(\d{4})\D(\d{2})\D(\d{2})$/;
console.log(regex.exec(str));
複製程式碼
方法三: test()
let str = "2018-10-18";
let regex = /^(\d{4})\D(\d{2})\D(\d{2})$/;
regex.test(str);
console.log(RegExp.$1, RegExp.$2, RegExp.$3);
複製程式碼
方法四: search()
let str = "2018-10-18";
let regex = /^(\d{4})\D(\d{2})\D(\d{2})$/;
str.search(regex);
console.log(RegExp.$1, RegExp.$2, RegExp.$3);
複製程式碼
方法五: replace()
let str = "2018-10-18";
let regex = /^(\d{4})\D(\d{2})\D(\d{2})$/;
let date = [];
str.replace(regex, function(match, year, month, day) {
date.push(year, month, day);
});
console.log(date);
複製程式碼
提取總結: 本質上是捕獲分組 推薦使用
match
和exec
其中, 最常用的是match
String.prototype.match();
引數: 一個正規表示式物件, 如果傳入一個非正規表示式物件, 則會隱式地使用new RegExp(obj)
將其轉換為一個RegExp
, 如果你為提供任何引數, 直接使用match()
, 那麼你會得到一個包含空字串的陣列[""]
返回值:如果字串匹配到了表示式, 會返回一個陣列, 陣列第一項是進行匹配完整的字串, 之後的項是用圓括號捕獲的結果, 如果沒有匹配到, 則返回
null
如果正規表示式不包含
g
標誌, 則str.match()
會返回和RegExp.exec()
相同的結果。而且返回的Array
擁有一個額外的input
屬性, 該屬性包含被解析的原始字串, 另外, 還擁有一個index
屬性, 該屬性表示匹配結果在原字元中的索引
如果正規表示式包含
g
標誌, 則該方法返回一個Array
, 它包含所有匹配的子字串而不是匹配物件, 捕獲組不會被返回( 即不返回index
屬性和input
屬性 )。如果沒有匹配到, 則返回null
。
RegExp.exec()
方法在一個指定字串中執行一個搜尋匹配, 返回一個結果陣列或null
String.match()
和 RegExp.exec()
的主要區別
- 所屬類不同
- 跟
g
有關 exec
只會匹配第一個符合的字串( 意味著g
對其不起作用 )和所有分組的反向引用, 雖然g
對其不生效,但其使用lastIndex
和while
迴圈, 可以達到g
的目的, 這點比match
強大match
返回的陣列內容, 跟正規表示式中是否帶g
有關係( 如果帶g
, 包含的是所有匹配的子字串 ) 如果不帶g
== 預設的exec
替換
使用正則的目的, 往往是匹配到對應的規則的字元, 下一步常常是替換^_^
正則處理中最強大的 API, 劃重點、劃重點、劃重點, 因為其常常被一些偽裝者, 假借替換之名, 做一些皮肉生意
Demo4 從 yyyy-mm-dd 替換成 yyyy/mm/dd
let str = "2018-10-18";
let regex = /-/g;
console.log(str.replace(regex, "/"));
複製程式碼
String.replace();
有兩種使用形式, 第二個引數時字串還是函式
一、當其為字串時如下字元有特殊含義
$1,$2 ... $99
匹配1-99
個分組捕獲的文字
二、當其為函式時, 回撥函式的引數具體意義
match
( 匹配內容 ),$1
( 分組1 ),$2
( 分組2 ),index
( 索引 ),input
( 原字元內容 )
總結
- 驗證一個字串( 精準匹配 )是否被包含, 使用
String.indexOf()
、String.includes()
- 驗證一個字串( 模糊匹配 )是否被包含, 使用
String.search()
、RegExp.test()
- 切分一段字串( 無論確認字元和規則字元 ), 使用
String.split(字串/正則)
- 提取分組捕獲資訊, 使用
String.match()
、RegExp.exec()
注意區分它們之間的區別 ->g
- 替換, 使用
String.replace(String/RegExp, string/function)
注意第二個引數的的規則資訊
傳送門 -> 正則基礎方法應用