麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > Regex > 正文

JavaScript系列文章:詳解正則表達(dá)式基本知識(shí)

2020-03-16 20:57:10
字體:
供稿:網(wǎng)友

正則表達(dá)式是一個(gè)精巧的利器,經(jīng)常用來在字符串中查找和替換,JavaScript語言參照Perl,也提供了正則表達(dá)式相關(guān)模塊,開發(fā)當(dāng)中非常實(shí)用,在一些類庫或是框架中,比如jQuery,就存在大量的正則表達(dá)式,所以說學(xué)好正則表達(dá)式,是提高開發(fā)技能的一項(xiàng)基本要求。那么今天博主就來詳細(xì)總結(jié)一下正則表達(dá)式的相關(guān)知識(shí),希望不熟悉的同學(xué)們,也能夠掌握正則表達(dá)式的原理及應(yīng)用。

在JS中,創(chuàng)建正則表達(dá)式有兩種方式,一種是字面量方式,一種是構(gòu)造器方式,如下所示:

var regex = //w+/;// 或者var regex = new RegExp('//w+');

大家也許注意到,使用字面量要比構(gòu)造器簡(jiǎn)潔得多,/w表示一個(gè)word,匹配單個(gè)字母、數(shù)字或下劃線,而使用RegExp構(gòu)造器時(shí),我們的正則變?yōu)榱?quot;//w",這是因?yàn)橐谧址斜硎疽粋€(gè)反斜杠/,我們需要對(duì)其轉(zhuǎn)義,也就是在前面再加一個(gè)轉(zhuǎn)義字符/。相信大家都知道,要在字面量正則中表達(dá)一個(gè)匹配反斜杠/的正則,只需寫成//這樣,但在字符串中表達(dá)這個(gè)正則,則是"////"這個(gè)樣子的,這是因?yàn)樽址星皟蓚€(gè)表示一個(gè)反斜杠/,后兩個(gè)也表示一個(gè)反斜杠/,最終在正則層面,結(jié)果還是//。

對(duì)于上面兩種創(chuàng)建形式,都可以加上一些后綴修飾符,這些修飾符可以單個(gè)使用,也可以組合起來使用:

 

復(fù)制代碼 代碼如下:

//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模式,對(duì)于匹配中文特別有用,而y是sticky,表示“粘連”,跟g很相似,都屬于全局匹配,但它們也有不同之處,這個(gè)我們后面會(huì)介紹。

正則相關(guān)方法

有了正則表達(dá)式對(duì)象了,如何使用呢?JS中的正則和字符串在原型中均提供相應(yīng)的方法,先來看看正則原型中的兩個(gè)方法:

RegExp.prototype.test(str);RegExp.prototype.exec(str);

上面的test()和exec()方法都需傳入一個(gè)字符串,對(duì)這個(gè)字符串進(jìn)行搜索和匹配,不同的是,test()方法會(huì)返回true或false,表示字符串和正則是否匹配,而exec()方法在匹配時(shí)返回一個(gè)匹配結(jié)果數(shù)組,如果不匹配,則只返回一個(gè)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']

對(duì)于exec()方法,如果正則中含有捕獲組,匹配后則會(huì)出現(xiàn)在結(jié)果數(shù)組中:

// (llo)是一個(gè)捕獲組var regex = /he(llo)/;var result = regex.exec('hello world');  // ['hello', 'llo']

開發(fā)當(dāng)中,test()方法一般用于用戶輸入驗(yàn)證,比如郵箱驗(yàn)證,手機(jī)號(hào)驗(yàn)證等等,而exec()方法一般用于從特定內(nèi)容中獲取有價(jià)值的信息,比如從用戶郵箱輸入中獲取其ID和郵箱類型,從手機(jī)號(hào)中獲取此號(hào)碼的歸屬地等等。

字符串相關(guān)方法

上面是正則原型中的兩個(gè)方法,現(xiàn)在來看看字符串原型中都提供了哪些可用的方法:

String.prototype.search(regexp);String.prototype.match(regexp);String.prototype.split([separator[, limit]]);String.prototype.replace(regexp|substr, newSubStr|function);

先來說說String#search()方法,它會(huì)根據(jù)正則參數(shù)對(duì)字符串進(jìn)行匹配搜索,如果匹配成功,就返回第一次匹配處的索引,如果匹配失敗,則返回-1。

// String#search()'hello world'.search(/hello/);  // 0'hello world'.search(/hi/);    // -1

String#match()方法跟RegExp#exec()方法相似,會(huì)返回結(jié)果數(shù)組,所不同的是,如果String#match()的正則參數(shù)中含有全局標(biāo)記g,則結(jié)果中會(huì)只出現(xiàn)匹配的子串,而忽略捕獲組,這一點(diǎn)與RegExp#exec()有些出入。且看下面代碼:

// String#match()'hello hello'.match(/he(llo)/);   // ['hello', 'llo']// String#match()遇到全局g修飾符時(shí)會(huì)舍棄捕獲組'hello hello'.match(/he(llo)/g);  // ['hello', 'hello']// RegExp#exec()仍舊包含捕獲組/he(llo)/g.exec('hello hello');   // ['hello', 'llo']

所以,如果需要總是將捕獲組作為結(jié)果返回,應(yīng)該使用RegExp#exec()方法,而不是String#match()方法。

接下來說說String#split()方法,這個(gè)方法用于將字符串分割,然后返回一個(gè)包含其子串的數(shù)組結(jié)果,其中separator和limit參數(shù)都是可選的,separator可指定為字符串或正則,limit指定返回結(jié)果個(gè)數(shù)的最大限制。如果separator省略,該方法的數(shù)組結(jié)果中僅包含自身源字符串;如果sparator指定一個(gè)空字符串,則源字符串將被以字符為單位進(jìn)行分割;如果separator是非空字符串或正則表達(dá)式,則該方法會(huì)以此參數(shù)為單位對(duì)源字符串進(jìn)行分割處理。下面代碼演示了該方法的使用:

// String#split()'hello'.split();         // ["hello"]'hello'.split('');        // ["h", "e", "l", "l", "o"]'hello'.split('', 3);       // ["h", "e", "l"]// 指定一個(gè)非空字符串var source = 'hello world';var result = source.split(' ');  // ["hello", "world"]// 或者使用正則表達(dá)式var result = source.split(//s/); // ["hello", "world"]如果separtor是一個(gè)正則表達(dá)式,并且正則中包含捕獲組,則捕獲組也會(huì)出現(xiàn)在結(jié)果數(shù)組中:// 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()方法,它會(huì)同時(shí)執(zhí)行查找和替換兩個(gè)操作。

從上面的函數(shù)簽名來看,該方法會(huì)接受兩個(gè)參數(shù):第一個(gè)參數(shù)可以是一個(gè)正則表達(dá)式,也可以是一個(gè)字符串,它們都表示將要匹配的子串;第二個(gè)參數(shù)可以指定一個(gè)字符串或是一個(gè)函數(shù),如果指定一個(gè)字符串,表示這個(gè)字符串將會(huì)替換掉已匹配到的子串,如果指定一個(gè)函數(shù),則函數(shù)的返回值會(huì)替換掉已匹配的子串。

String#replace()方法最終會(huì)返回一個(gè)新的已經(jīng)過替換的字符串。下面分別演示了replace方法的使用:

// String#replace()var source = 'matchandsplitandreplace';var result = source.replace('and', '-'); // "match-splitandreplace"// 或者var result = source.replace(/and/, function() { return '-';});                    // "match-splitandreplace"

從上面的代碼中可以看到,'and'被替換成了'-',但我們同時(shí)也注意到,只有第一個(gè)'and'被替換了,后面的并沒有被處理。這里我們就需要了解,String#replace()方法只對(duì)第一次出現(xiàn)的匹配串進(jìn)行替換,如果我們需要全局替換,需要將第一個(gè)參數(shù)指定為正則表達(dá)式,并追加全局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"

初學(xué)者看到上面的代碼,可能會(huì)覺得疑惑,對(duì)于第二個(gè)參數(shù),直接指定一個(gè)字符串也挺簡(jiǎn)單的嘛,我們?yōu)楹我褂靡粋€(gè)函數(shù)然后再返回一個(gè)值呢。我們看看下面的例子就知道了:

// String#replace() 替換函數(shù)的參數(shù)列表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"

上面代碼中,第一個(gè)參數(shù)是正則表達(dá)式,其中包含了兩個(gè)捕獲組(and)和(nd),第二個(gè)參數(shù)指定一個(gè)匿名函數(shù),其函數(shù)列表中有一些參數(shù):match, p1, p2, offset, string,分別對(duì)應(yīng)匹配到的子串、第一個(gè)捕獲組、第二個(gè)捕獲組、匹配子串在源字符串中的索引、源字符串,我們可以稱這個(gè)匿名函數(shù)為“replacer”或“替換函數(shù)”,在替換函數(shù)的參數(shù)列表中,match、offset和string在每一次匹配時(shí)總是存在的,而中間的p1、p2等捕獲組,String#replace()方法會(huì)根據(jù)實(shí)際匹配情況去填充,當(dāng)然,我們還可以根據(jù)arguments獲取到這些參數(shù)值。

下面是代碼運(yùn)行后的控制臺(tái)打印結(jié)果:

js正則表達(dá)式基本語法,js正則表達(dá)式語法,javascript正則表達(dá)式

現(xiàn)在來看,指定一個(gè)函數(shù)要比指定一個(gè)字符串功能強(qiáng)的多,每次匹配都能獲取到這些有用的信息,我們可以對(duì)其進(jìn)行一些操作處理,最后再返回一個(gè)值,作為要替換的新子串。所以推薦在調(diào)用String#replace()方法時(shí),使用上面這種方式。

上面是String類與正則相關(guān)的常用方法,需要注意的是,String#search()和String#match()方法簽名中參數(shù)均為正則對(duì)象,如果我們傳遞了其他類型的參數(shù),會(huì)被隱式轉(zhuǎn)換為正則對(duì)象,具體的步驟是先調(diào)用參數(shù)值的toString()方法得到字符串類型的值,然后調(diào)用new RegExp(val)得到正則對(duì)象:

// -> String#search(new RegExp(val.toString()))'123 123'.search(1);    // 0'true false'.search(true); // 0'123 123'.search('//s');  // 3var 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()方法不會(huì)將字符串轉(zhuǎn)為正則表達(dá)式對(duì)象,對(duì)于其他類型值,只會(huì)調(diào)用其toString()方法將參數(shù)值轉(zhuǎn)為字符串,也不會(huì)進(jìn)一步向正則轉(zhuǎn)換,大家可以親自測(cè)試一下。

以上就是正則的相關(guān)基本知識(shí)及常用方法,限于篇幅原因,更多關(guān)于正則表達(dá)式的內(nèi)容,博主會(huì)安排在下一篇中介紹和講解,敬請(qǐng)期待。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到正則表達(dá)式頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 海外中文字幕在线观看 | 黄色毛片一级 | 黑人一级片视频 | 中文字幕在线播放第一页 | 欧美成人综合视频 | 成人18在线| 精品一区二区三区欧美 | 九九热在线视频观看 | 久久免费激情视频 | 国产wwww| 懂色av懂色aⅴ精彩av | 亚洲国产精品二区 | 日本aaa一级片 | 欧美一级淫片免费视频1 | 欧美精品免费一区二区三区 | 亚洲欧美在线视频免费 | 欧美第1页 | 国产一级一片免费播放 | 国产精品久久久久一区二区 | 国产精品高潮99久久久久久久 | 久久人| 国产精品毛片va一区二区三区 | 日韩视频区 | 久久精品免费网站 | 欧美视频一级 | 国产精品午夜未成人免费观看 | 欧美在线小视频 | 久久精品视频国产 | 欧美韩国一区 | 欧洲精品久久 | 久久精品欧美视频 | 在线观看免费视频麻豆 | 欧美视频一区二区三区 | 色婷婷久久久久久 | 国产精品久久久久久久亚洲按摩 | 成人一区二区在线观看视频 | 最近日本电影hd免费观看 | 黄色特级 | 欧美综合日韩 | 精品国产99久久久久久宅男i | 一级大片视频 |