您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“JS中的正則表達(dá)式函數(shù)有哪些”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“JS中的正則表達(dá)式函數(shù)有哪些”吧!
在JavaScript中,能夠使用正則表達(dá)式的函數(shù)有(排除了過時的方法):
RegExp.prototype
RegExp.prototype.test()
RegExp.prototype.exec()
String.prototype
String.prototype.match()
String.prototype.matchAll()
String.prototype.replace()
String.prototype.replaceAll()
String.prototype.search()
String.prototype.split()
RegExp.prototype
首先我們要講解的是RegExp對象上的兩個方法
RegExp.prototype.test()
作用:檢測給定的字符串中是否有滿足正則的匹配
代碼示例:
簡單的匹配,根據(jù)匹配的結(jié)果確定是否匹配成功。
const reg = /\d{4}-\d{2}-\d{2}/; const str1 = '2000-02-22'; const str2 = '20-20-20'; console.log(reg.test(str1)); // true console.log(reg.test(str2)); // false
上面的正則表達(dá)式?jīng)]有設(shè)置全局的標(biāo)志符g,如果設(shè)置了全局的標(biāo)志符的話,我們在使用這個方法的時候就要小心一些了。因為如果正則表達(dá)式設(shè)置了全局的標(biāo)識符g,那么對于同一個正則表達(dá)式來說,在運行test方法的時候,如果匹配成功的話,它會修改這個正則對象的lastIndex屬性,可能會在下次匹配的時候?qū)е乱恍﹩栴},我們下面來看一個例子。
const reg = /abc/g; const str1 = 'abcd'; const str2 = 'abcdabcd'; console.log(reg.lastIndex); // 0 console.log(reg.test(str1)); // true console.log(reg.lastIndex); // 3 console.log(reg.test(str1)); // false console.log(reg.lastIndex); // 0 console.log(reg.test(str2)); // true console.log(reg.lastIndex); // 3 console.log(reg.test(str2)); // true
上面的例子很好地說明了這種情況,如果我們設(shè)置了全局標(biāo)識符g的話,只要我們當(dāng)前的匹配是成功的,那么接下來如果再次使用同樣的正則進(jìn)行匹配的話就可能會出現(xiàn)問題,因為上一個成功的匹配導(dǎo)致正則表達(dá)式對象的lastIndex屬性的值發(fā)生了變化,那么下次進(jìn)行匹配的時候是從lastIndex位置開始的,所以就可能會出現(xiàn)一些問題。
注意事項:如果在使用test方法的時候,需要注意正則表達(dá)式是否帶有g(shù)標(biāo)識符。如果這個正則表達(dá)式需要進(jìn)行多次的匹配的話,最好不要設(shè)置g標(biāo)識符。除非你知道自己確實需要這樣做。
使用場景:
假如有這樣一個需求,你需要判斷用戶輸入的用戶名是否滿足需求,需求如下:(1)用戶名長度需要是8-16位。(2)用戶名可以包含數(shù)字,字母(大小寫都可以),下劃線。(3)數(shù)字和字母是必須包含的。
當(dāng)然對于熟悉正則表達(dá)式的你來說,這不是一個問題,能用一行代碼解決的問題絕不用兩行代碼去解決。你可以很快可以通過使用test方法來解決這個問題。
const validNameRE = /^(?=_*(?:\d+_*[a-zA-Z]+|[a-zA-Z]+_*\d+))\w{8,16}$/; // 假如這是用戶輸入的用戶名 const userInputName = '1234567890'; // 檢查用戶輸入的用戶名是否合乎要求 const isValidName = validNameRE.test(userInputName); // false
在平時的開發(fā)中,如果需要判斷頁面所處的宿主環(huán)境的話,我們也會使用test方法去判斷當(dāng)前頁面所處的環(huán)境。例如,你需要判斷當(dāng)前頁面所處的環(huán)境是不是iPhone的話,你可能會寫出這樣的判斷:
const iPhoneReg = /iPhone/; console.log(iPhoneReg.test(navigator.userAgent)); // true
RegExp.prototype.exec()
作用:這個方法是比較常用的一個方法,在給定的字符串中進(jìn)行匹配,返回一個匹配的結(jié)果數(shù)組或者null。通常情況下我們會使用這個方法來提取字符串中符合匹配的一些字符串。
代碼示例:
需要注意的是,如果沒有符合的匹配,返回的結(jié)果是null,而不是一個空數(shù)組[]。所以當(dāng)我們需要判斷是否有匹配的結(jié)果的時候,不能憑感覺覺得返回的值是一個空的數(shù)組[]。
const reg1 = /(\d{2}):(\d{2}):(\d{2})/; const str1 = 'Sat Aug 22 2020 17:31:55 GMT+0800 (中國標(biāo)準(zhǔn)時間)'; const str2 = 'Sat Aug 22 2020'; console.log(reg1.exec(str1)); // ["17:31:55", "17", "31", "55", index: 16, input: "Sat Aug 22 2020 17:31:55 GMT+0800 (中國標(biāo)準(zhǔn)時間)", groups: undefined] console.log(reg1.exec(str2)); // null
從上面的代碼中我們可以看到,如果沒有匹配結(jié)果的話,返回的結(jié)果是null。如果能夠匹配成功的話,返回的結(jié)果是一個數(shù)組。在這個結(jié)果數(shù)組中,第0項表示正則表達(dá)式匹配的內(nèi)容。其中第1..n項表示的是正則表達(dá)式中括號的捕獲內(nèi)容,對于上面的示例來說,第1..3項表示的是捕獲時間的時分秒。數(shù)組還有額外的屬性index和input,其中index表示正則表達(dá)式匹配到的字符串在原字符串中的位置。input表示原始待匹配的字符串。
注意事項:
注意正則表達(dá)式是否設(shè)置了g標(biāo)識符,如果設(shè)置了g標(biāo)識符,那么我們可以使用這個正則表達(dá)式進(jìn)行全局的搜索??梢钥聪旅娴拇a示例。
const reg = /\d/g; const str = '654321'; let result; while ((result = reg.exec(str))) { console.log( `本次匹配到的數(shù)字是:${result[0]}, 正則表達(dá)式的 lastIndex 的值是:${ reg.lastIndex }` ); }
輸出的結(jié)果如下:
本次匹配到的數(shù)字是:6, 正則表達(dá)式的 lastIndex 的值是:1 本次匹配到的數(shù)字是:5, 正則表達(dá)式的 lastIndex 的值是:2 本次匹配到的數(shù)字是:4, 正則表達(dá)式的 lastIndex 的值是:3 本次匹配到的數(shù)字是:3, 正則表達(dá)式的 lastIndex 的值是:4 本次匹配到的數(shù)字是:2, 正則表達(dá)式的 lastIndex 的值是:5 本次匹配到的數(shù)字是:1, 正則表達(dá)式的 lastIndex 的值是:6
需要注意的是,如果上面匹配的正則表達(dá)式?jīng)]有設(shè)置g標(biāo)識符,或者在while循環(huán)的條件判斷中使用的是正則表達(dá)式的字面量的話,都會造成“死循環(huán)”。因為那樣的話,每次循環(huán)開始的時候,正則表達(dá)式的lastIndex屬性都會是0,導(dǎo)致result一直都是有值的,所以就導(dǎo)致了“死循環(huán)”。所以我們在while循環(huán)中使用exec方法的時候一定要小心一些。
使用場景:這個方法主要用來在原始文本中提取一些我們想要的關(guān)鍵信息,所以只要是這樣的一個需求場景,都可以使用正則表達(dá)式的exec方法去處理。比如:
對用戶輸入內(nèi)容中的鏈接進(jìn)行自動識別,然后對相應(yīng)的鏈接內(nèi)容進(jìn)行樣式和功能上的處理。
可以提取url中的查詢參數(shù),如果我們需要自己把url中的查詢參數(shù)提取出來的話,使用exec方法也是一個選擇。
如果你閱讀過vue的源碼的話,在編譯模塊中的文本解析使用到了exec方法,有興趣的話大家可以看一看相關(guān)的代碼實現(xiàn)。
當(dāng)然還有很多的場景可以使用exec方法去處理的,大家在平時的開發(fā)中有沒有使用過exec方法處理一些問題呢?可以在下面留言,我們大家一起討論一下,加深一下對這個方法的理解。
String.prototype
接下來我們來講解一下String.prototype上面有關(guān)正則的一些方法。
String.prototype.match()
作用:這個方法返回字符串匹配正則表達(dá)式的結(jié)果。
代碼示例:
const reg = /\d/; const str = 'abc123'; console.log(str.match(reg)); // ["1", index: 3, input: "abc123", groups: undefined]
注意事項:
1. 沒有匹配到結(jié)果的返回結(jié)果是null。
const reg = /\d/; const str = 'abc'; console.log(str.match(reg)); // null
2. 是否設(shè)置了g標(biāo)識符,如果沒有設(shè)置g的話,match的返回結(jié)果跟對應(yīng)的exec的返回結(jié)果是一樣的。如果設(shè)置了g標(biāo)識符的話,返回的結(jié)果是與正則表達(dá)式相匹配的結(jié)果的集合。
const reg = /\d/g; const str = 'abc123'; console.log(str.match(reg)); // ["1", "2", "3"]
3. 如果match方法沒有傳遞參數(shù)的話,返回的結(jié)果是[''],一個包含空字符串的數(shù)組。
const str = 'abc123'; console.log(str.match()); // ["", index: 0, input: "abc123", groups: undefined]
4. 如果match方法傳遞的參數(shù)是一個字符串或者數(shù)字的話,會在內(nèi)部隱式調(diào)用new RegExp(regex),將傳入的參數(shù)轉(zhuǎn)變?yōu)橐粋€正則表達(dá)式。
const str = 'abc123'; console.log(str.match('b')); // ["b", index: 1, input: "abc123", groups: undefined]
使用場景:
簡單獲取url中的查詢參數(shù):
const query = {}; // 首先使用帶有g(shù)標(biāo)識符的正則,表示全局查找 const kv = location.search.match(/\w*=\w*/g); if (kv) { kv.forEach(v => { // 使用不帶g標(biāo)識符的正則,需要獲取括號中的捕獲內(nèi)容 const q = v.match(/(\w*)=(\w*)/); query[q[1]] = q[2]; }); }
String.prototype.matchAll()
作用:這個方法返回一個包含所有匹配正則表達(dá)式以及正則表達(dá)式中括號的捕獲內(nèi)容的迭代器。需要注意的是這個方法存在兼容性,具體內(nèi)容可以查看String.prototype.matchAll。
代碼示例:
const reg = /(\w*)=(\w*)/g; const str = 'a=1,b=2,c=3'; console.log([...str.matchAll(reg)]);
String.prototype.matchAll()
注意事項:
1. 跟match方法相同的地方是,如果傳遞給matchAll方法的參數(shù)不是一個正則表達(dá)式的話,那么會隱式調(diào)用new RegExp(obj)將其轉(zhuǎn)換為一個正則表達(dá)式對象。 傳遞給matchAll的正則表達(dá)式需要是設(shè)置了g標(biāo)識符的,如果沒有設(shè)置g標(biāo)識符,那么就會拋出一個錯誤。
const reg = /(\w*)=(\w*)/; const str = 'a=1,b=2,c=3'; console.log([...str.matchAll(reg)]); // Uncaught TypeError: String.prototype.matchAll called with a non-global RegExp argument
2. 在可以使用matchAll的情況下,使用matchAll比使用exec方法更便捷一些。因為在全局需要匹配的情況下,使用exec方法需要配合循環(huán)來使用,但是使用matchAll就可以不使用循環(huán)。
3. matchAll方法在字符串執(zhí)行匹配的過程中,正則表達(dá)式的lastIndex屬性不會更新。更多詳情可以參考String.prototype.matchAll()。
使用場景:
還是以上面的獲取url中的查詢參數(shù)這個小功能來實踐一下:
const query = {}; const kvs = location.search.matchAll(/(\w*)=(\w*)/g); if (kvs) { for (let kv of kvs) { query[kv[1]] = kv[2]; } } console.log(query);
String.prototype.replace()
作用:這個方法在平時的開發(fā)中應(yīng)該比較常用,那么它的作用就是使用替換物replacement替換原字符串中符合某種模式pattern的字符串。其中替換物可以是一個字符串,或者返回值是字符串的函數(shù);模式可以是正則表達(dá)式或者字符串。
代碼示例:
因為這個函數(shù)的入?yún)⒖梢允遣煌念愋?,所以對每種類型的入?yún)⑽覀兌紒韺嵺`一下吧。
1. pattern是字符串,replacement也是字符串。這種形式在平時的開發(fā)中使用的比較多。
const pattern = 'a'; const replacement = 'A'; const str = 'aBCD'; console.log(str.replace(pattern, replacement)); // ABCD
2. pattern是正則表達(dá)式,replacement是字符串。
const pattern = /__(\d)__/; const replacement = "--$$--$&--$`--$'--$1--"; const str = 'aaa__1__bbb'; console.log(str.replace(pattern, replacement)); // aaa--$--__1__--aaa--bbb--1--bbb
如果replacement是字符串,那么在這個字符串中可以使用一些特殊的變量,具體可參考Specifying a string as a parameter。
pattern是正則表達(dá)式,replacement是函數(shù)。
const pattern = /__(?<number>\d)__/; const replacement = function(match, p1, offset, str, groups) { console.log(`匹配到的字符串是:${match}\n捕獲到的內(nèi)容是:${p1}\n匹配的位置是:${offset}\n原始待匹配的字符串是:${str}\n命名的捕獲內(nèi)容是:${JSON.stringify(groups)}`); return '======'; }; const str = 'aaa__1__bbb'; console.log(str.replace(pattern, replacement)); // aaa======bbb
其中控制臺的輸出如下所示:
匹配到的字符串是:__1__ 捕獲到的內(nèi)容是:1 匹配的位置是:3 原始待匹配的字符串是:aaa__1__bbb 命名的捕獲內(nèi)容是:{"number":"1"}
如果你對replacement是函數(shù)這種情況不是很了解的話可以看看Specifying a function as a parameter,里面會有詳細(xì)的解釋,這里就不在具體解釋了。
注意事項:
需要注意的地方就是當(dāng)我們的pattern是正則表達(dá)式的時候,要注意是否設(shè)置了g標(biāo)識符,因為如果沒有設(shè)置g標(biāo)識符的話,只會進(jìn)行一次匹配。設(shè)置了g標(biāo)識符的話,會進(jìn)行全局的匹配。
使用場景:
對于前端來說,對用戶的輸入進(jìn)行校驗時很常見的需求。假如我們有一個輸入框,只允許用戶輸入數(shù)字,我們可以這樣處理:
const reg = /\D/g; const str = 'abc123'; console.log(str.replace(reg, '')); // 123
這樣就能夠保證用戶的輸入只有數(shù)字了。
String.prototype.replaceAll()
As of August 2020 the replaceAll() method is supported by Firefox but not by Chrome. It will become available in Chrome 85.
這個方法和replace方法的作用差不多,從名字上就能夠知道replaceAll是全局的替換。因為這個方法的兼容性問題,我們需要在Firefox瀏覽器上進(jìn)行試驗。
const pattern = 'a'; const replacement = 'A'; const str = 'aBCDa'; console.log(str.replace(pattern, replacement)); // ABCDa console.log(str.replaceAll(pattern, replacement)); // ABCDA
注意事項:如果給函數(shù)傳遞的pattern參數(shù)是個正則表達(dá)式的話,這個正則表達(dá)式必須設(shè)置了g標(biāo)識符,不然會拋出一個錯誤。
const pattern = /a/; const replacement = 'A'; const str = 'aBCDa'; console.log(str.replace(pattern, replacement)); // ABCDa console.log(str.replaceAll(pattern, replacement)); // Uncaught TypeError: replaceAll must be called with a global RegExp
String.prototype.search()
作用:這個方法用來在字符串中尋找是否含有特定模式的匹配,如果找到對應(yīng)的模式,返回匹配開始的下標(biāo);沒有找到的話返回-1。
代碼示例:
const reg = /\d/; const str1 = '123'; const str2 = 'abc'; console.log(str1.search(reg)); // 0 console.log(str2.search(reg)); // -1
注意事項:
如果傳入的參數(shù)不是一個正則表達(dá)式的話,會隱式的調(diào)用new RegExp(regexp)將其轉(zhuǎn)換為一個正則表達(dá)式。
沒有找到相應(yīng)匹配的時候,返回的值是-1;所以大家在使用這個方法做判斷的時候要注意,只有返回值是-1的時候,才表示沒有找到相應(yīng)的匹配。
使用場景:
如果你需要找到特定匹配在字符串中的位置的話,那么可以使用search方法。
const reg = /\d/; const str = 'abc6def'; console.log(str.search(reg)); // 3
String.prototype.split()
作用:將一個字符串按照分割器進(jìn)行分割,將分割后的字符串片段組成一個新的數(shù)組,其中分割器separator可以是一個字符串或者一個正則表達(dá)式。
代碼示例:
1. 分割器separator是字符串:
const str = 'hello, world!'; console.log(str.split('')); // ["h", "e", "l", "l", "o", ",", " ", "w", "o", "r", "l", "d", "!"]
2. 分割器separator是正則表達(dá)式:
const str = 'abc1abc2abc3'; const separator = /\w(?=\d)/; console.log(str.split(separator)); // ["ab", "1ab", "2ab", "3"]
注意事項:
1. 如果split方法沒有傳遞參數(shù)的話,會返回一個包含原字符串的數(shù)組:
const str = 'hello, world!'; console.log(str.split()); // ["hello, world!"]
2. 因為JavaScript的字符串是使用UTF-16進(jìn)行編碼的,該編碼使用一個16比特的編碼單元來表示大部分常見的字符,使用兩個編碼單元表示不常用的字符。所以對于一些不常用的字符來說,在使用split方法進(jìn)行字符串分割的時候可能會出現(xiàn)一些問題:
const str = '??????'; console.log(str.split('')); // ["?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?"]
如何解決這種類型的問題呢?第一種方法是使用數(shù)組的擴(kuò)展運算符:
const str = '??????'; console.log([...str]); // ["?", "?", "?", "?", "?", "?"]
第二種方法是使用設(shè)置了u標(biāo)識符的正則表達(dá)式:
const str = '??????'; const separator = /(?=[\s\S])/u; console.log(str.split(separator)); // ["?", "?", "?", "?", "?", "?"]
如果傳入的正則表達(dá)參數(shù)中含有捕獲的括號,那么捕獲的內(nèi)容也會包含在返回的數(shù)組中:
const str = 'abc1abc2abc3'; const separator = /(\w)(?=\d)/; console.log(str.split(separator)); // ["ab", "c", "1ab", "c", "2ab", "c", "3"]
split方法還可以傳入第二個參數(shù),用來控制返回的數(shù)組的長度:
const str = 'hello, world!'; console.log(str.split('', 3)); // ["h", "e", "l"]
使用場景:
在實際的開發(fā)中,最常用的場景就是將一個字符串轉(zhuǎn)換為一個數(shù)組了:
const str = 'a/b/c/d/e'; console.log(str.split('/')); // ["a", "b", "c", "d", "e"]
到此,相信大家對“JS中的正則表達(dá)式函數(shù)有哪些”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。