您好,登錄后才能下訂單哦!
這篇文章主要介紹JavaScript中正則表達式基本知識有哪些,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
在JS中,創建正則表達式有兩種方式,一種是字面量方式,一種是構造器方式,如下所示:
var regex = /\w+/; // 或者 var regex = new RegExp('\\w+');
大家也許注意到,使用字面量要比構造器簡潔得多,\w表示一個word,匹配單個字母、數字或下劃線,而使用RegExp構造器時,我們的正則變為了"\\w",這是因為要在字符串中表示一個反斜杠\,我們需要對其轉義,也就是在前面再加一個轉義字符\。相信大家都知道,要在字面量正則中表達一個匹配反斜杠\的正則,只需寫成\\這樣,但在字符串中表達這個正則,則是"\\\\"這個樣子的,這是因為字符串中前兩個表示一個反斜杠\,后兩個也表示一個反斜杠\,最終在正則層面,結果還是\\。
對于上面兩種創建形式,都可以加上一些后綴修飾符,這些修飾符可以單個使用,也可以組合起來使用:
復制代碼 代碼如下:
/\w+/g; // global search
/\w+/i; // ignore case
/\w+/m; // multi-line
/\w+/u; // unicode
/\w+/y; // sticky
/\w+/gi;
new RegExp('\\w+', 'gi');
從英文注釋來看,相信大家都大概都略知一二了,需要注意的是u和y修飾符,它們是ES6新增的特性,u表示啟用Unicode模式,對于匹配中文特別有用,而y是sticky,表示“粘連”,跟g很相似,都屬于全局匹配,但它們也有不同之處,這個我們后面會介紹。
正則相關方法
有了正則表達式對象了,如何使用呢?JS中的正則和字符串在原型中均提供相應的方法,先來看看正則原型中的兩個方法:
RegExp.prototype.test(str); RegExp.prototype.exec(str);
上面的test()和exec()方法都需傳入一個字符串,對這個字符串進行搜索和匹配,不同的是,test()方法會返回true或false,表示字符串和正則是否匹配,而exec()方法在匹配時返回一個匹配結果數組,如果不匹配,則只返回一個null值,下面來看看兩者的差異:
// RegExp#test() var regex = /hello/; var result = regex.test('hello world'); // true // RegExp#exec() var regex = /hello/; var result = regex.exec('hello world'); // ['hello']
對于exec()方法,如果正則中含有捕獲組,匹配后則會出現在結果數組中:
// (llo)是一個捕獲組 var regex = /he(llo)/; var result = regex.exec('hello world'); // ['hello', 'llo']
開發當中,test()方法一般用于用戶輸入驗證,比如郵箱驗證,手機號驗證等等,而exec()方法一般用于從特定內容中獲取有價值的信息,比如從用戶郵箱輸入中獲取其ID和郵箱類型,從手機號中獲取此號碼的歸屬地等等。
字符串相關方法
上面是正則原型中的兩個方法,現在來看看字符串原型中都提供了哪些可用的方法:
String.prototype.search(regexp); String.prototype.match(regexp); String.prototype.split([separator[, limit]]); String.prototype.replace(regexp|substr, newSubStr|function);
先來說說String#search()方法,它會根據正則參數對字符串進行匹配搜索,如果匹配成功,就返回第一次匹配處的索引,如果匹配失敗,則返回-1。
// String#search() 'hello world'.search(/hello/); // 0 'hello world'.search(/hi/); // -1
String#match()方法跟RegExp#exec()方法相似,會返回結果數組,所不同的是,如果String#match()的正則參數中含有全局標記g,則結果中會只出現匹配的子串,而忽略捕獲組,這一點與RegExp#exec()有些出入。且看下面代碼:
// String#match() 'hello hello'.match(/he(llo)/); // ['hello', 'llo'] // String#match()遇到全局g修飾符時會舍棄捕獲組 'hello hello'.match(/he(llo)/g); // ['hello', 'hello'] // RegExp#exec()仍舊包含捕獲組 /he(llo)/g.exec('hello hello'); // ['hello', 'llo']
所以,如果需要總是將捕獲組作為結果返回,應該使用RegExp#exec()方法,而不是String#match()方法。
接下來說說String#split()方法,這個方法用于將字符串分割,然后返回一個包含其子串的數組結果,其中separator和limit參數都是可選的,separator可指定為字符串或正則,limit指定返回結果個數的最大限制。如果separator省略,該方法的數組結果中僅包含自身源字符串;如果sparator指定一個空字符串,則源字符串將被以字符為單位進行分割;如果separator是非空字符串或正則表達式,則該方法會以此參數為單位對源字符串進行分割處理。下面代碼演示了該方法的使用:
// String#split() 'hello'.split(); // ["hello"] 'hello'.split(''); // ["h", "e", "l", "l", "o"] 'hello'.split('', 3); // ["h", "e", "l"] // 指定一個非空字符串 var source = 'hello world'; var result = source.split(' '); // ["hello", "world"] // 或者使用正則表達式 var result = source.split(/\s/); // ["hello", "world"] 如果separtor是一個正則表達式,并且正則中包含捕獲組,則捕獲組也會出現在結果數組中: // String#split() 正則捕獲組 var source = 'matchandsplit'; var result = source.split('and'); // ["match", "split"] var result = source.split(/and/); // ["match", "split"] // 正則中含捕獲組 var result = source.split(/(and)/); // ["match", "and", "split"]
最后來介紹一下String#replace()方法,它會同時執行查找和替換兩個操作。
從上面的函數簽名來看,該方法會接受兩個參數:第一個參數可以是一個正則表達式,也可以是一個字符串,它們都表示將要匹配的子串;第二個參數可以指定一個字符串或是一個函數,如果指定一個字符串,表示這個字符串將會替換掉已匹配到的子串,如果指定一個函數,則函數的返回值會替換掉已匹配的子串。
String#replace()方法最終會返回一個新的已經過替換的字符串。下面分別演示了replace方法的使用:
// String#replace() var source = 'matchandsplitandreplace'; var result = source.replace('and', '-'); // "match-splitandreplace" // 或者 var result = source.replace(/and/, function() { return '-'; }); // "match-splitandreplace"
從上面的代碼中可以看到,'and'被替換成了'-',但我們同時也注意到,只有第一個'and'被替換了,后面的并沒有被處理。這里我們就需要了解,String#replace()方法只對第一次出現的匹配串進行替換,如果我們需要全局替換,需要將第一個參數指定為正則表達式,并追加全局g修飾符,就像下面這樣:
// String#replace() 全局替換 var source = 'matchandsplitandreplace'; var result = source.replace(/and/g, '-'); // "match-split-replace" var result = source.replace(/and/g, function() { return '-'; }); // "match-split-replace"
初學者看到上面的代碼,可能會覺得疑惑,對于第二個參數,直接指定一個字符串也挺簡單的嘛,我們為何要使用一個函數然后再返回一個值呢。我們看看下面的例子就知道了:
// String#replace() 替換函數的參數列表 var source = 'matchandsplitandreplace'; var result = source.replace(/(a(nd))/g, function(match, p1, p2, offset, string) { console.group('match:'); console.log(match, p1, p2, offset, string); console.groupEnd(); return '-'; }); // "match-split-replace"
上面代碼中,第一個參數是正則表達式,其中包含了兩個捕獲組(and)和(nd),第二個參數指定一個匿名函數,其函數列表中有一些參數:match, p1, p2, offset, string,分別對應匹配到的子串、第一個捕獲組、第二個捕獲組、匹配子串在源字符串中的索引、源字符串,我們可以稱這個匿名函數為“replacer”或“替換函數”,在替換函數的參數列表中,match、offset和string在每一次匹配時總是存在的,而中間的p1、p2等捕獲組,String#replace()方法會根據實際匹配情況去填充,當然,我們還可以根據arguments獲取到這些參數值。
下面是代碼運行后的控制臺打印結果:
現在來看,指定一個函數要比指定一個字符串功能強的多,每次匹配都能獲取到這些有用的信息,我們可以對其進行一些操作處理,最后再返回一個值,作為要替換的新子串。所以推薦在調用String#replace()方法時,使用上面這種方式。
上面是String類與正則相關的常用方法,需要注意的是,String#search()和String#match()方法簽名中參數均為正則對象,如果我們傳遞了其他類型的參數,會被隱式轉換為正則對象,具體的步驟是先調用參數值的toString()方法得到字符串類型的值,然后調用new RegExp(val)得到正則對象:
// -> String#search(new RegExp(val.toString())) '123 123'.search(1); // 0 'true false'.search(true); // 0 '123 123'.search('\\s'); // 3 var o = { toString: function() { return '\\s'; } }; '123 123'.search(o); // 3 // -> String#match(new RegExp(val.toString())) '123 123'.match(1); // ["1"] 'true false'.match(true); // ["true"] '123 123'.match('\\s'); // [" "] var o = { toString: function() { return '1(23)'; } }; '123 123'.match(o); // "123", "23"]
而split()和replace()方法不會將字符串轉為正則表達式對象,對于其他類型值,只會調用其toString()方法將參數值轉為字符串,也不會進一步向正則轉換,大家可以親自測試一下。
以上是“JavaScript中正則表達式基本知識有哪些”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。