文章目錄
- 正則運算式的作用
- 創建正則運算式的方式
- 字面量形式
- 使用物件的形式創建正則運算式
- 小案例-實作輸入字符高亮
- 選擇符
- 對轉義的理解
- 字符邊界約束
- 小案例
- 元字符
- 用 [ ] 巧妙匹配所有字符
- 模式符
- 多行匹配
- 字符屬性
- lastIndex屬性
- 有效率的y模式
- 原子表和原子組的基本使用
- 郵箱驗證
- 原子組的替換操作
- 不記錄分組
- 多種重復匹配基本使用
- 禁止貪婪
- 斷言匹配
- ?= 后邊是什么的
- ?<= 前面是什么的
- ?! 后面不是什么的就匹配
- ?<! 前面不是什么的就匹配
- 字串正則方法
- $符號在正則替換中的使用
正則運算式的作用
簡單來講正則運算式的作用就是進行字串的增刪改查,雖然javascritpt語言已經有及其完善的操作字串的api,但是正則運算式會讓你操作字串更簡單方便
創建正則運算式的方式
字面量形式
需要注意的是 字面量形式的正則運算式 是沒有辦法操作變數的,如下
const reg = "sattre is smart"
let x = 's'
console.log(/x/.test(reg)); //false
除非改成這樣
// eval是把字串變成js運算式
console.log(eval(`/${x}/`).test(str));
使用物件的形式創建正則運算式
使用物件的形式創建的好處就是能夠直接接受正則變數
const x = 'a'
let regs = new RegExp(x)
let str = 'All we need is love'
let reg = new RegExp('A', 'g') // 第二個引數代表匹配的模式
console.log(reg.test(str));
小案例-實作輸入字符高亮
其實就是和瀏覽器的ctrl+f功能差不多
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="main">
All we need is love
</div>
</body>
<script>
const cin = prompt('輸入想要高亮內容')
const reg = new RegExp(cin, 'g')
let mainDiv = document.querySelector('#main')
console.log(mainDiv);
mainDiv.innerHTML = mainDiv.innerHTML.replace(reg, matched => {
return `<span style="color:red">${matched}</span>`
})
</script>
</html>
選擇符
‘ | ’ 此為選擇符,選擇符兩邊的字符都可以匹配,都有效
let str1 = 'a'
let str2 = 'b'
console.log(/a|b/.test(str1)); //true
console.log(/a|b/.test(str2)); //true
對轉義的理解
自己的話理解就是,有些特殊符號如:{} [] . 等本來在正則運算式中就已經賦予了它的含義,如果單獨使用會按照本身賦予的含義編譯,如果需要匹配這些特殊符號本身,那么需要在這些符號前面加上一個 ‘’ 來加以區別
小數點本身的正則含義是除換行符外的任何字符
// 匹配小數點 \.
let price = 23.34
console.log(/\d+\.\d+/.test(23.34)); //true
但是需要注意的來了
如果你是用物件方法宣告的正則運算式的話,你需要在轉義字符前多使用一次 ’ / ’ ,因為物件宣告正則運算式傳入的是字串,他的決議方式不同
如下
let reg = new RegExp('\d+\.\d+')
console.log(reg.test(price)); //false
console.log('/\d+\.\d+/');

需要改成:
let reg1 = new RegExp('\\d+\\.\\d+')
console.log(reg1.test(price)); //true
再來一個
const url = 'https://space.bilibili.com/17819768/'
console.log(/https?:\/\/\w+\.\w+\.\w+\/\d+\//.test(url)); //true
字符邊界約束
- ^ : 限定以其后面的第一個字符為開始
- $: 限定以其前面的第一個字符為結束
寫一個監測必須以數字開頭結束的字串
let str = '2dasdjifeiorepo'
let str2 = '3dsf5'
console.log(/^\d\w+\d$/.test(str));
console.log(/^\d\w+\d$/.test(str2));
注意:^ 如果用在[ ] 中 還有除了[ ] 中的字符以外都可以匹配的意思
let str = `張三:155565666523,李四:2564154156561`
console.log(str.match(/[^\d,:]+/g));
小案例
檢測輸入3-6字符的正確格式
注意 :這里如果沒有 ^ $ 的話 任意的超過6個的字串都會成功,因為沒有開始和結束的限定,match會在字串中任意取6個字符,所以也算作是成功的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="text" name="user">
<span></span>
<script>
let input = document.querySelector("[name='user']")
let span = document.querySelector('span')
console.log(input);
input.addEventListener('keyup', function () {
// console.log(this.value.match(/^\w{3,6}$/));
if (this.value.match(/^\w{3,6}$/)) {
span.innerHTML = '正確格式'
}else{
span.innerHTML = '請輸入3-6位字符'
}
})
</script>
</body>
</html>
元字符
| 元字符 | 匹配 |
|---|---|
| \d | 匹配數字 |
| \D | 匹配除了數字的其他字符 |
| \s | 匹配空白(換行符也算) |
| \S | 除了空白的其他字符 |
| \w | 匹配字母 數字 下劃線 |
| \W | 除了字母數字下劃線 |
| . | 匹配除了換行符的任意字符 |
匹配一個郵箱
let str = `#$%483023989@qq.com`
let str2 = `483023989@qq.com`
console.log(str.match(/^\w+@\w+\.\w+$/));
console.log(str2.match(/^\w+@\w+\.\w+$/));

用 [ ] 巧妙匹配所有字符
[ ] 代表可選
如下,如果不加[ ] 代表完整匹配abc ,加了 [ ] ,代表可以匹配abc中的任意一個字符
let str = 'aaaabsdsc'
console.log(str.match(/[abc]/g));
console.log(str.match(/abc/g));

可以用 [\s\S] [\d\D] 匹配所有字符
let str = '$%^&*()(*&^&*(sfhsdjf asdoia ..fdsdgf nsefxg\][iogjpsf'
console.log(str.length);
console.log(str.match(/[\s\S]/g));

模式符
- i : 不區分大小寫
- g: 全域匹配
let str = 'Www'
console.log(str.match(/w/gi)); //["W", "w", "w"]
多行匹配
到網上搜尋了一下,多行匹配的方式還是挺多的,這里主要先記一下,模式符 m 是可以進行多行匹配的
// 多行匹配
let str = `
#1 js,200元 #
#2 vue,500元 #
#3 angular,199元 # song
#4 node.js,188元 #
`
let res = str.match(/\s*#\d+\s+.+\s+#\s+$/gm).map(item => {
item = item.replace(/\s*#\d+\s*/, '').replace(/#/, '')
let [name, price] = item.split(",")
return { name, price }
})
console.log(res);
字符屬性
\p 后面加上{x} x代表要匹配的字符屬性 具體意思如下
元字符 含義
- \p{L} 所有字母
- \p{N} 所有數字,類似于 \d
- [\p{N}\p{L}] 所有數字和所有字母,類似于 \w
- \P{L} 不是字母,等價于 [^\p{L}]
- \P{N} 不是數字,等價于 [^\p{N}]
let str = "sadhusafsafha.啥事愛上撒大聲地?!"
// 匹配字符
console.log(str.match(/\p{L}/gu));
// 匹配標點符號
console.log(str.match(/\p{P}/gu));
// 匹配漢字
console.log(str.match(/\p{sc=Han}/gu));

模式符 u
此修飾符標識能夠正確處理大于\uFFFF的Unicode字符,
也就是說,會正確處理四個位元組的UTF-16編碼,
此修飾符是ES2015新增,更多正則運算式新特性可以參閱ES2015 正則運算式新增特性一章節,
比如有些時候,一些寬位元組的字符匹配不到,就需要用到模式符/u
lastIndex屬性
lastIndex是正則運算式中的一個屬性,它是控制正則運算式開始收手的位置,使用全域模式會使這個屬性發生變化
let str = 'nihaowoshizhongguoren'
let reg = /\w/g
console.log(reg.lastIndex);
console.log(reg.exec(str));
console.log(reg.lastIndex);
console.log(reg.exec(str));
while ((res = reg.exec(str))) {
console.log(res);
}

有效率的y模式
和g的區別就是,g模式只要還有滿足條件的字符就會繼續下去匹配,而y模式只要下一個字符不滿足匹配條件,就會停止匹配,它的作用是讓匹配更具有效率,一旦遇到條件不符合的就不會再檢測后面的字符了
let str = '尼采的電話是:516515614,111111111,2222222222 沒重要的事千萬不要打給他,因為他已經瘋了'
let reg = /(\d+),?/y
reg.lastIndex = 7
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));

原子表和原子組的基本使用
[] 代表原子表:可選擇匹配 ()代表原子組
let str = 'paul_sattre'
console.log(str.match(/st/g)); //需要st一起才能匹配
console.log(str.match(/[st]/g)); //需要只要有s 或者 t 就可以匹配
let date1 = '2021/4/9'
let date2 = '2021-4-9'
console.log(date1.match(/\d+[-\/]\d+[-\/]\d+/));
console.log(date2.match(/\d+[-\/]\d+[-\/]\d+/));

其實上面還是有點缺陷
就是將date改成這樣的時候 2021-4/9 前后兩個符號不一致的時候還是能夠匹配到,這個時候就可以用到原子組了
let date1 = '2021/4/9'
let date2 = '2021-4-9'
let date3 = '2021-4/9'
console.log(date1.match(/\d+([-\/])\d+\1\d+/));
console.log(date2.match(/\d+([-\/])\d+\1\d+/));
console.log(date3.match(/\d+([-\/])\d+\1\d+/));

加了一個 () 后面的\1代表要和前面的()相同才能行
郵箱驗證
// 郵箱驗證
let str = '483023989@qq.com.cn'
let reg = /^[\w]+@[\w]+(\.[\w]+)+/
//["483023989@qq.com.cn", ".cn", index: 0, input: "483023989@qq.com.cn", groups: undefined]
console.log(str.match(reg));
// (\.[\w]+)+ 表示括號之內的內容有1個或多個

原子組的替換操作
替換h標簽為p標簽
let str = `
<h1>hello</h1>
<h2>asdas</h2>
<h3>dasdad</h3>
`
let reg = /<(h[1-6])>([\s\S]+)<\/\1>/gi
// console.log(str.replace(reg, '<p>$2</p>'));
/**
*
<p>hello</p>
<p>asdas</p>
<p>dasdad</p>
*/
let res = str.replace(reg, ($0, $1, $2) => {
return `<p>${$2}</p>`
})
/**
* 上面回呼函式中的 $0 代表的是整個匹配到的內容,之后的$1 $2 就是從左
* 到右的原子組匹配到的內容
*/
console.log(res);

不記錄分組
https? 代表前面的字符s可以有也可以沒有 代表不記錄到我們的
下面的(?:\w+.) 原子組中的 ?: 代表不記錄到我們的組編號之中
let str = `
https://www.nihao.com
http://nihao.com
`
let reg = /https?:\/\/((?:\w+\.)?\w+\.(?:com|cn|net))/gi
let urls = []
while ((res = reg.exec(str))) {
urls.push(res[1])
}
console.log(urls);
所以有沒有www都能匹配到

多種重復匹配基本使用
+ : 一個或多個
* : 零個或多個
{a,b}: a-b范圍內的出現次數
?: 零個或1個
// 多種重復匹配基本使用
let str = 'asddddddddd'
let str2 = 'as'
console.log(str.match(/sd+/)); //1個或多個
console.log(str2.match(/sd*/)); //0個或多個
console.log(str.match(/sd{2,3}/)); // 2或3個
console.log(str.match(/sd?/)); // 0個或1個

// 重復匹配對原子組的影響
let str = 'asdddddsd'
console.log(str.match(/(sd)+/g)); //["sd", "sd"]
限定用戶名為3-8位并且是以字母開頭
// 限定用戶名為3-8位并且是以字母開頭
let username = 'a_Coding'
let username1 = '2fdsdfd'
let username2 = 's'
let username3 = 'asdsadsadsad';
console.log(/^[a-z]\w{2,7}$/i.test(username));
console.log(/^[a-z]\w{2,7}$/i.test(username1));
console.log(/^[a-z]\w{2,7}$/i.test(username2));
console.log(/^[a-z]\w{2,7}$/i.test(username3));

禁止貪婪
使用正則/sd+/ 匹配上面字串時+會默認貪婪多個d,+后面加個?就只會匹配一個d了 這就是禁止貪婪
// 禁止貪婪
let str = 'asdddddd'
/**
* 使用正則/sd+/ 匹配上面字串時+會默認貪婪多個d
* +后面加個?就只會匹配一個d了 這就是禁止貪婪
*/
console.log(str.match(/sd+/)); //sdddddd
console.log(str.match(/sd+?/)); //sd
console.log(str.match(/sd*/)); //sdddddd
console.log(str.match(/sd*?/)); //sd
console.log(str.match(/sd{1,4}/));//sdddd
console.log(str.match(/sd{1,4}?/));//sd

斷言匹配
?= 后邊是什么的
應該注意的是:斷言只是對前面匹配的條件限定,并不參與實際的匹配結果中,
?= 中的等于號后面如果是個a,那么前面的匹配字符需要后面是a才會被匹配
// 斷言匹配 ?= 后邊是什么的
let str = '我愛你,你愛他'
let reg = /愛(?=你)/ //匹配后面有一個,號的love
console.log(str.replace(reg, '不愛')); //我不愛你,你愛他
使用斷言規范價格
let lessons = `
js,343元,400次
node.js,300.00元,134次
java,500元,432次
`
let reg = /(\d+)(.00)?(?=元)/gi
lessons = lessons.replace(reg, (v, ...args) => {
console.log(args);
args[1] = args[1] || '.00'
return args.slice(0, 2).join('')
})
console.log(lessons);

?<= 前面是什么的
理解上面的第一個斷言這個也就能猜到意思了
// ?<= 前面是什么的
let str = '我愛你,你愛他'
let reg1 = /(?<=你)愛/
console.log(str.replace(reg1, '不愛'));// 我愛你,你不愛他
使用斷言模糊電話號碼
let users = `
喬丹電話:54088888888,
艾弗森電話;08888888845
`
// 給電話號碼的后4位變成*
let reg = /(?<=\d{7})\d+/g
// console.log(users.match(reg));
users = users.replace(reg, '*'.repeat(4))
console.log(users);

?! 后面不是什么的就匹配
let str = 'hfewhieuwhf43758435efhiuewfhiew'
let reg = /[a-z]+(?!\d+)$/i //取后面不是數字的字母 注意這里的這個$非常重要
console.log(str.match(reg)); //efhiuewfhiew
?<! 前面不是什么的就匹配
let str = 'asdae334dsfdsff'
let reg = /(?<!\d+)[a-z]+/i
console.log(str.match(reg)); //asdae
字串正則方法
- search : 回傳索引值,找不到就是-1
- match: 回傳匹配后的字符結果 陣列
- matchAll 回傳全域匹配的迭代物件
- split 分割字串形成陣列
// 字串正則方法
let str = 'i love you'
console.log(str.search('u')); // 回傳索引值,找不到就是-1
console.log(str.search(/o/));
// 回傳匹配后的字符結果 陣列
console.log(str.match(/o/)); //["o", index: 3, input: "i love you", groups: undefined]
// matchAll split
let date = '2001-1/1'
console.log(date.split(/[-\/]/)); //["2001", "1", "1"]
matchAll
<body>
<h1>all we need is love</h1>
<h2>all we need is love</h2>
<h3>all we need is love</h3>
<script>
let reg = /<(h[1-6])>([\s\S]+?)<\/\1>/gi
const content = document.body.innerHTML.matchAll(reg)
// console.log(content);
let res = []
for (const it of content) {
// console.log(it);
res.push(it[2])
}
console.log(res);
let str = 'woainiw'
// 為低端瀏覽器自定義原型方法matchALl
String.prototype.matchAll = function (reg) {
let res = this.match(reg)
if (res) {
let str = this.replace(res[0], '^'.repeat(res[0].length))
let match = str.matchAll(reg) || []
return [res, ...match]
}
}
console.log(str.matchAll(/(w)/i));
</script>
</body>

$符號在正則替換中的使用
$& 代表匹配到的內容
$` 代表匹配到的前面內容
$’ 代表匹配到的后面內容
let date = '2013/5/6'
let str = '(010)88888888 (020)88888888'
let reg = /\((\d{3,4})\)(\d{7,8})/g
console.log(str.replace(reg, "$1-$2"));
// 010-88888888 020-88888888
// $& 代表匹配到的內容
// $` 代表匹配到的前面內容
// $' 代表匹配到的后面內容
let str = '我愛你'
console.log(str.replace(/愛/, '不$&')); //我不愛你
console.log(str.replace(/愛/, "$`")); //我我你
console.log(str.replace(/愛/, "$'")); //我你你
參考:https://www.bilibili.com/video/BV12J41147fC?from=search&seid=7924071864413293768
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/278102.html
標籤:其他
