成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

【愣錘筆記】一支穿云箭、正則來相見

wangbjun / 1881人閱讀

摘要:表示進(jìn)行多行匹配。如果正則表達(dá)式中含有子表達(dá)式,那么該數(shù)組后續(xù)的項依次為匹配到的第一個子表達(dá)式的匹配結(jié)果,第二個第個。關(guān)于正則方法有一點必須要提,很容易導(dǎo)致錯誤的情況。這時候直接使用該正則表達(dá)式對進(jìn)行方法調(diào)用,卻返回了。匹配前一項至少次。

有人說,一行正則抵得上100行代碼……

正則表達(dá)式,每門語言都有,在我們的js開發(fā)中,最常見的使用場景:一是表單驗證,像是登錄注冊啊,用戶輸入檢測啊,不管在前臺項目還是后臺管理系統(tǒng),都會經(jīng)常使用;二是,在開發(fā)一些重數(shù)據(jù)交互的后臺管理系統(tǒng)或者應(yīng)用的時候,更是會大量的使用,各種字符匹配,表達(dá)式檢測等等。

正則本身知識點不是很多,但是由于各種字符意思容易忘記,所以需要經(jīng)常復(fù)習(xí),多使用就記住了。

創(chuàng)建一個正則表達(dá)式:

// 通過RegExp構(gòu)造函數(shù)創(chuàng)建
var regex1 = new RegExp("[a-z]", "g");
// 通過直接字面量創(chuàng)建
var regex2 = /[a-z]/g;

這兩種方式都可以創(chuàng)建正則表達(dá)式,以上兩種方式創(chuàng)建了一個等價的正則表達(dá)式,均為匹配字母a到z。但是日常開發(fā)中,基本都是通過直接字面量創(chuàng)建:兩個反斜杠之間為正則表達(dá)式,反斜杠后面跟著修飾符i、g、m。修飾符可寫可不寫,也可以同時寫多個,他們的意思分別是:

i:表示忽略大小寫,就是在字符串匹配的時候不區(qū)分大小寫。
g:表示全局匹配,即所有滿足的字符都會被匹配到,一直匹配到字符串的結(jié)尾。
m:表示進(jìn)行多行匹配。這個是什么意思呢,舉個例子吧:

var str = "hello world 
 my name is LengChui."

可看到這個字符串中有一個 換行符,正常匹配時,到 就結(jié)束了,也就是只會匹配到這一行的結(jié)尾。但是如果加了m修飾符,會繼續(xù)往后面匹配,一直匹配到字符串的最終結(jié)尾。

當(dāng)然了,修飾符可以同時寫多個,例如:var regex = /[a-z]/ig;表示匹配所有的字母a到z,且不區(qū)分大小寫。這樣,對于字符串"a123H"就會匹配到a和Z


正則表達(dá)式方法:test()和exec()

所有的正則表達(dá)式都有test和exec這兩個方法。

test()方法:測試字符串中是否包含了匹配該正則表達(dá)式的子串,如果包含了這樣的子串,那么返回true,否則返回false

// 定義一個匹配hello字符串的正則表達(dá)式
var reg = /hello/g;
var str = "hello world";
// 如果字符串str中匹配到了hello字符串,則打印如下信息
if (reg.test(str)) {
    console.log("字符串str中含有hello子串")
}

這個方法相信在驗證用戶輸入內(nèi)容的時候,會經(jīng)常使用到。例如,相信很多人寫過類似下面的正則驗證用戶輸入值的合法性代碼:

// 點擊提交按鈕,驗證輸入值,提交ajax請求
document.getElementById("submitButton").addEventListener("click", function (event) {
    // 獲取用戶輸入的手機號
    var phoneNumber = document.getElementById("phone");
    // 驗證手機號格式的正則
    var regPhone = /^1[3|4|5|8]d{9}$/g;
    // 檢測輸入的合法性,進(jìn)行錯誤提示
    if (!phoneNumber) {
        $tim("請輸入手機號!")
        return;
    }
    if (!regPhone.test(phoneNumber)) {
        $tip("手機號格式不正確,請重新輸入!");
        return;
    }
    // 如果驗證成功,提交ajax請求
    $.ajax(………………)
}, false);


exec方法:接收一個參數(shù),即待檢測的字符串。它返回一個增強的數(shù)組對象,數(shù)組的第一項為匹配到的字符串。如果正則表達(dá)式中含有子表達(dá)式,那么該數(shù)組后續(xù)的項依次為匹配到的第一個子表達(dá)式的匹配結(jié)果,第二個……第n個。如果沒有匹配到任何內(nèi)容,則返回null。

通過例子來說明exec的使用方法:

// 定義一個字符串
var str = "hello javascript, hello javaspring"
// 定義一個正則表達(dá)式,該表達(dá)式匹配任意java后跟任意大小寫字母的字符串
// 注意這里的正則表達(dá)式?jīng)]有加g,后面會說明exec的正則表達(dá)式加g與不加g的區(qū)別
var reg = /java([a-zA-Z]+)/;
// 調(diào)用exec方法
var execResult = reg.exec(str);
console.log(execResult)

看下最終的打印結(jié)果:


可以看到返回一個數(shù)組,數(shù)組的第一項為匹配到的結(jié)果,第二項為第一個子表達(dá)式的匹配結(jié)果,如果還有其他子表達(dá)式,會依次往后排。同時這個數(shù)組對象還有以下幾個屬性:

    groups: undefined

    index// 當(dāng)前匹配結(jié)果的開始下標(biāo)。這里匹配的javascript字符串的開始下標(biāo)為6。

    input // 待匹配的字符串,其實就是我們的這里的str字符串

注意上述正則表達(dá)式/java([a-zA-Z]+)/沒有加修飾符g,這意味著不需要全局匹配。這種情況下,exec()方法只會匹配依次便最終匹配結(jié)束了,那么如果繼續(xù)調(diào)用execResult = reg.exec(str);,則會重新開始匹配,即從字符串0的位置開始重新匹配并返回新的匹配結(jié)果。其結(jié)果肯定是一樣的。如下面例子:

var str = "hello javascript, hello javaspring"
var reg = /java([a-zA-Z]+)/;
// 第一次匹配調(diào)用并打印結(jié)果
var execResult = reg.exec(str);
console.log(execResult);
// 重新調(diào)用并打印結(jié)果
execResult = reg.exec(str);
console.log(execResult);


可以看到兩次調(diào)用的匹配結(jié)果是一樣的。這里不禁就有人說了,那不是廢話了,調(diào)用同一個表達(dá)式,結(jié)果不就一樣嘛。然而,還真不是。在介紹這個之前,我們先簡單提一下正則表達(dá)式的實例屬性,告訴了我們該正則表達(dá)式的一些基本信息。這個不需要記,了解一下即可:

var reg2 = /a/igm; // 定義一個不區(qū)分大小寫、全局匹配、多行匹配字符串a(chǎn)的正則表達(dá)式
console.dir(reg2) // 打印出該對象


下表中列出了所有的正則表達(dá)式實例屬性。

實例屬性含義
globalBoolean值,指明正則表達(dá)式是否包含g修飾符
ignoreCaseBoolean值,指明正則表達(dá)式是否包含i修飾符
lastIndex

若正則表達(dá)式包含g修飾符,該屬性指明執(zhí)行exec()test()方法后,最后一次匹配結(jié)果字符串后面的第一個字符的位置

source只讀屬性,給出了正則表達(dá)式的內(nèi)容,即除了斜杠和選項字符之外的整個正則表達(dá)式。
multilineBoolean值,指定搜索字符串時是否跨行搜索,即是否包含m修飾符,該屬性的另外一個名稱是$*

了解了這個之后,我們回過頭來繼續(xù)說exec()方法。在調(diào)用exec()方法的正則表達(dá)式?jīng)]有加修飾符g,即不是全局匹配的模式下,每次調(diào)用exec()之后,本次的正則匹配也就最終結(jié)束了,注意是最終結(jié)束了。下次該正則表達(dá)式再次調(diào)用exec()方法時會從字符串開頭開始匹配,可以立即為開始了一次新的正則匹配。

那么如果調(diào)用exec()方法的正則表達(dá)式是全局匹配的話(加了修飾符g),該正則表達(dá)式每次調(diào)用exec()方法結(jié)束后,其實例屬性lastIndex都會指向本次匹配結(jié)果字符串后面一個字符的位置,直到匹配結(jié)果返回null,即沒有匹配到任何結(jié)果的時候,才會將其lastIndex屬性重置為0。繼續(xù)看這個例子演示:

var str = "hello javascript, hello javaspring"
// 定義匹配任何java后跟任意大小寫字母的字符串,注意這里是全局匹配
var reg = /java([a-zA-Z]+)/g;

// 該正則表達(dá)式第一次調(diào)用exec()方法并打印匹配結(jié)果和其實例屬性lastIndex
var execResult = reg.exec(str);
console.log(execResult, reg.lastIndex);

// 第二次調(diào)用
execResult = reg.exec(str);
console.log(execResult, reg.lastIndex);

// 第三次調(diào)用
execResult = reg.exec(str);
console.log(execResult, reg.lastIndex);


從打印結(jié)果可以看出,第一次匹配到了字符串javascript,其開始下標(biāo)為6,實例屬性lastIndex16,即javascript字符串后面的一個字符“逗號”的位置下標(biāo)。第二次調(diào)用的匹配結(jié)果為javaspring,lastIndex的值為34。第三次調(diào)用沒有匹配到任何結(jié)果,所以返回了null,其lastIndex的結(jié)果也被重置為了0。

關(guān)于正則方法exec()有一點必須要提,很容易導(dǎo)致錯誤的情況。當(dāng)調(diào)用exec()方法的正則表達(dá)式是全局匹配的情況下,對一個字符串匹配后,如果沒有匹配到最終結(jié)果,即沒有返回null的情況下,使用該正則表達(dá)式對新字符串進(jìn)行exec()方法調(diào)用時,切記一定要先將該正則表達(dá)式的實例屬性lastIndex重置為0。看例子:

var str = "hello javascript, hello javaspring"
var str2 = "javascript and html"

// 定義匹配任何java后跟任意大小寫字母的正則表達(dá)式,全局匹配
var reg = /java([a-zA-Z]+)/g;

// 使用該正則的exec()方法匹配字符串str
var execResult = reg.exec(str);
console.log(execResult, reg.lastIndex);

// 使用該正則的ecev()方法匹配字符串str2
execResult = reg.exec(str2);
console.log(execResult, reg.lastIndex);


從打印結(jié)果可以看出,對于str字符串的正則匹配時,正常返回了結(jié)果,其lastIndex的值為16,還并沒有最終匹配結(jié)束,lastIndex值也沒有重置為0。這時候直接使用該正則表達(dá)式對str2進(jìn)行exec()方法調(diào)用,卻返回了null。為什么呢,正常應(yīng)該也可以匹配到str2字符的javascript字符啊。這是因為,對str調(diào)用后,其lastIndex值被賦值為了16,那么下次對str2調(diào)用的時候,便從下標(biāo)16開始調(diào)用,str2中從下標(biāo)16開始匹配自然而然是沒有匹配到任何字符串。注意,正則表達(dá)式的實例屬性lastIndex是可讀可寫的屬性,所以為了避免這種情況,在對str2正則匹配前,先將其lastIndex屬性重置為0

reg.lastIndex = 0;
execResult = reg.exec(str2);
console.log(execResult, reg.lastIndex);


元字符

所謂元字符,其實就是在正則表達(dá)式的不同上下文中有著特殊意義的標(biāo)點符號,請看下面:

. * + ( ) $ /  ");

嗯~沒錯,就是這幾個字符,通過不同的組合可以幫我們構(gòu)建出非常強大的正則表達(dá)式。注意,這些字符帶有特殊意義,如果就只是單純的項匹配這些字符,需要加/進(jìn)行轉(zhuǎn)義,例如.就只是匹配一個點,沒有其他特殊意義。下面我們一一進(jìn)行介紹。

. : 匹配除了換行符和回車之外的任何字符,eg: /./ 匹配一個除換行回車之外的任意字符;

[] :? 匹配方括號里面的任意字符。方括號內(nèi)可以是1個字符也可以是多個字符。eg: [ab] 匹配字符a,也可以匹配字符b;[a- z] 可以匹配字母a到z任意一個,-表示的意思;[0-9]可以匹配數(shù)字0到9;也可以混合使用[a-zA-Z0-9]可以匹配小寫字母a到z,大寫字母A-Z,可以匹配數(shù)字0-9;

[^] : 匹配除了方括號內(nèi)^后面的任意字符,可以理解為[]的取反操作。eg: /[^ab]/ 匹配除了a和b以外的任意字符。?

| : 或,即匹配 | 左邊或者右邊的表達(dá)式。eg: /a|b/ 匹配字符a或者字符b

*? : 匹配0個或多個前面的表達(dá)式, eg: /a*/ 匹配0或者多個a,a、aa、aaa、aaaa等都是滿足匹配規(guī)則的。

+ : 匹配1個或多個前面的表達(dá)式,和*類似,但是至少要滿足匹配一次。eg: /a+/ 可以匹配1個或多個a,隱藏a、aa、aaa等都是合法的,但是bcdf是不符合匹配規(guī)則的,因為沒有至少匹配到一個a。

");:? 匹配0和或1個前面的表達(dá)式,可以理解為前一項是可選的。和*+類似,但是要注意三者的區(qū)別。

{n, m} : 匹配前一項n到m次,包含n次和m次。eg: /[0-9]{6,8}/ 可以匹配6到8位數(shù)字。

{n, } :? 匹配前一項至少n次。 eg: /[0-9]{11, }/ 至少匹配11位數(shù)字

{n} : 匹配前一項n次。 eg: /[0-9]{5}/? 匹配5位數(shù)字

需要注意的是:*");可以匹配前一項0次,因此像類似 /a*/.test("bcdf") 是返回true的,因為他匹配到了0個a;而/a*/.exec("bcdf")也是返回了一個第一項是一個空字符串的數(shù)組,而不是返回null,也是因為匹配了0個a。

另一個需要注意的是,正則匹配默認(rèn)都是貪婪匹配。什么意思呢?就是盡可能多的匹配,比如用/a+/來匹配字符串a(chǎn)aabbbb時,會匹配到aaa,即盡可能多匹配。類似的重復(fù)匹配時都是貪婪匹配的。然而可以使用這些元字符加上");/a+");再對aaabbbb匹配時,則只會匹配到一個a,其他的*");? {}"); ");同理。

: 和一些字符組合使用會有特殊的意義:

w元符號,等價于[a-zA-Z0-9_],匹配任何字母、數(shù)字、下劃線字符,這樣的字符也稱為單詞字符
W元符號,等價于[^a-zA-Z0-9_],匹配除了字母、數(shù)字、下劃線字符之外的任何字符
d元符號,等價于[0-9],匹配任何單個的數(shù)字字符
D元符號,等價于[^0-9],匹配除了數(shù)字之外的任何單個字符
s元符號,匹配空白字符,即空格、Tab字符和回車換行符
S元字符,匹配任何非空白字符

^ :匹配字符串的開始位置,或多行匹配模式中(即加了修飾符m)每一行的開始位置

$ : 匹配字符串的結(jié)束位置,或多行匹配模式下(即加了修飾符m)每一行的結(jié)束位置

^$這兩個元字符,在日常開發(fā)中幾乎是最常見的了,幾乎大部分的正則表達(dá)式都是這種形式的:/^表達(dá)式$/。都知道是它的意思是匹配字符串的開始和結(jié)束為止,猛一看好像理解了,但是細(xì)細(xì)揣摩貌似又不知道到底是什么意思。下面我就細(xì)細(xì)說來:

這兩個字符和上面其他元字符不同的是,這個字符匹配的是位置,而不是具體匹配的某個字符。這么說,應(yīng)該清晰一點了,所以/^表達(dá)式$/就是從字符串開頭的位置開始,一直到結(jié)束的位置,都必須滿足匹配規(guī)則才行。再次強調(diào)下,^$匹配的都只是一個位置,位置,位置。

 : 匹配單詞邊界。這個也是用來匹配位置的,通俗的講,就是匹配區(qū)分單詞分割位置的。例如,兩個單詞之間的位置,第一個單詞前面的位置,最后一個單詞后面的位置,都是匹配的單詞位置。eg: /java/可以匹配單詞java,即匹配java字符兩邊都是單詞邊界的結(jié)果,對于字符串I love java very much則匹配成功,而字符串I love javascript very much則匹配不成功。因為第一句的java兩邊空格都是單詞邊界,而javascipt雖然包含了java單詞,但是只滿足左邊是單詞邊界,其子串java的右邊是script子串,而不是單詞邊界,所以不滿足兩邊都是單詞邊界的匹配規(guī)則。

console.log(/java/.test("java")) // true
console.log(/java/.test("javascript")) // false

B:匹配非單詞邊界,是的反義詞。eg:/Bscript/ 對于字符串javascript是可以匹配成功的,因為其子串script的左側(cè)是java字符串,不是單詞邊界。而對于字符串script則是不成功的,因為其左側(cè)什么都沒有,即左側(cè)就是一個單詞邊界。

console.log(/Bscript/.test("javascript")) // true
console.log(/Bscript/.test("script")) // false


斷言

js里面的斷言只支持先行斷言,又分為正向先行斷言負(fù)向先行斷言。這么說比較繞口,讓人云里霧里的感覺,所以還是直接上例子:

");: 正向先行斷言,其實就是說");/java(");只能匹配javascript,不能匹配javaspring,java123等等。

");: 負(fù)向先行斷言,即");/java(");?只能匹配javaspring,java123等等,但不能匹配javascript。


分組/子表達(dá)式

() : 子表達(dá)式,也可以叫分組,就是把括號里面的表達(dá)式作為一個整體來處理。一個正則表達(dá)式里面可以有多個子表達(dá)式,子表達(dá)式里面也可以嵌套子表達(dá)式。在我們介紹exec()方法的時候說過,exec()返回一個增強的數(shù)組,數(shù)組第一項為該正則表達(dá)式的匹配結(jié)果,第二項及以后為對應(yīng)的子表達(dá)式的匹配結(jié)果。

// 沒有子表達(dá)式的正則exec()方法
var reg1 = /[a-z][0-9]/;
var str1 = "hello123";
console.log(reg1.exec(str1))

// 添加了子表達(dá)式的正則exec()方法		
var reg2 = /([a-z])([0-9])/;
var str2 = "hello123";
console.log(reg2.exec(str2))

// 子表達(dá)式嵌套的情況
var reg3 = /(([a-z])([0-9]))/;
var str3 = "hello123";
console.log(reg3.exec(str3))


打印結(jié)果可以看出,加子表達(dá)式之后,比沒加之前多返回了幾項,這幾項分別對應(yīng)每個子表達(dá)式匹配的結(jié)果。注意,當(dāng)有嵌套的情況下,子表達(dá)式的順序,其實就是所有的左括號從左到右出現(xiàn)的順序。

每一子表達(dá)式匹配到的值都會被保存下來,分別存在1,2,3……里面,也會保存在$1,$2,$3……兩者的區(qū)別是,1這種類型的是使用在正則表達(dá)式中的,$1這種類型的是使用在字符串的方法中。關(guān)于字符串方面會在文章后面的內(nèi)容講解。先看個例子吧:

// 需要匹配第一第二位都是數(shù)字,第三位和第一位必須相同,第四位和第二位必須相同的正則表達(dá)式
var reg4 = /(d)(d)12/;
// 打印為true,因第一位和第二位都是數(shù)字,第三位和第一的值相同,第四位和第二位的值也相同
console.log(reg4.test("1212")) // true
// 打印結(jié)果為false,因為第三位的值和第一位的不一樣
console.log(reg4.test("1232"))

從這正則表達(dá)式可以看到,要求匹配的第一位和第二位都是數(shù)字,那么后面的1和2是什么意思呢,就是說1就是第一個(d)匹配到的結(jié)果,2就是第二個(d)匹配到的結(jié)果。注意,這里的意思并不是說第三位第四位是和第一第二位匹配的規(guī)則相同的,而是說,加入第一位匹配到了數(shù)字2,那么第三位也只能數(shù)字2,如果第二位匹配到了數(shù)字4,那么第四位也必須是4才可以。那么最終的匹配結(jié)果就是類似1212, 4747等。eg: 左引號和右引號必須相匹配的情況,可以這樣子:/[""][^""]*1/,即首先是單引號或者雙引號,后面是0到多個非單引號雙引號字符,最后如果第一個匹配了單引號則最后一個必須是單引號,如果第一個匹配到了雙引號則最后也必須是雙引號。

注意在子表達(dá)式嵌套的情況下,1,2……對應(yīng)的其實就是左括號的值,不管它怎么嵌套。這么說應(yīng)該更好理解了。

那么問題來了,如果不想保存子表達(dá)式的值呢,或者說多個子表達(dá)式中我不想保存某些子表達(dá)式的值怎么辦呢?

("); : 一個問號加一個冒號,成為無記憶匹配。他依然是對括號中里面的內(nèi)容進(jìn)行分組,但是不會捕獲子模式,即不會保存匹配到的值到1,2,3……中?,F(xiàn)在我修改一下上面的例子再看:

// 需要匹配第一第二位都是數(shù)字,第三位和第二位必須相同
var reg4 = /(");false,因第一位和第二位都是數(shù)字,第三位和第二位的值不一樣
console.log(reg4.test("1212"))
// 打印結(jié)果為true,因為第三位的值和第二位的值相同
console.log(reg4.test("1232"))

從表達(dá)式可以看出,我們的第一個(");子表達(dá)式添加了無記憶匹配模式,所以后面的1里面存放的值就變成了后面的(d)匹配的結(jié)果。因此,子表達(dá)式設(shè)置了無記憶匹配模式后,1,2……便不會再存儲其匹配結(jié)果了,而是存儲后面沒有設(shè)置無記憶匹配模式的子表達(dá)式。


字符串方法中正則表達(dá)式的運用

字符串方法小伙伴們都很熟悉,這里只說和正則匹配相關(guān)的方法。正則表達(dá)式本身就是用來處理字符串的匹配規(guī)則,那么相應(yīng)的字符串方法,當(dāng)然得和正則勾搭點關(guān)系啦~~好了,拉回正題,下面先列舉和正則有關(guān)的字符串方法:

match(regex)返回所有與正則表達(dá)式regex相匹配的子串?dāng)?shù)組
replace(regex,replacement)字符串替換。將字符串中的regex指定的子串替換為子串replacement
search(regex)字符串搜索。查找正則表達(dá)式regex指定的模式在字符串中的開始位置
split(regex)字符串分割。使用正則表達(dá)式regex分割字符串,并將分割的結(jié)果以數(shù)組的形式返回

? (1) match方法:返回一個由匹配結(jié)果組成的數(shù)組,如果沒有匹配到任何結(jié)果則返回null。該方法接收一個正則表達(dá)式作為參數(shù),如果不是正則表達(dá)式,它會首先調(diào)用new RegExp()將參數(shù)轉(zhuǎn)換成正則表達(dá)式。

注意:如果正則參數(shù)不帶修飾符g,match方法不會進(jìn)行全局匹配,其效果和不加修飾符g的exec()方法返回的結(jié)果是一樣的。如果忘記了exec()方法,可以往回翻翻回顧一下。

"aaaa".match("b") // 返回null,因為沒有匹配到任何內(nèi)容

下面看下正則表達(dá)式不帶修飾符g的例子:

console.log("abcd");.match(/a/)) 


在不是全局匹配的情況下,其返回結(jié)果和exec()方法如出一轍,如果表達(dá)式含有子表達(dá)式的話,數(shù)組的第二項及后續(xù)項是子表達(dá)式的匹配結(jié)果。如果是全局匹配的話,則會返回一個由所有匹配結(jié)果組成的數(shù)組:

// 不含有子表達(dá)式的全局匹配
console.log("1a2b3c4d5");.match(/[0-9]/g))

// 含有子表達(dá)式的全局匹配
console.log("1a2b3c4d5");.match(/[0-9]|(a)/g))


結(jié)果非常的直觀,在全局匹配模式下會返回所有匹配結(jié)果組成的數(shù)組。但是如果正則表達(dá)式含有子表達(dá)式的話,也會把子表達(dá)式的匹配結(jié)果返回出來。

? (2) replace()方法:用于字符串的替換,并返回替換后的結(jié)果。接收兩個參數(shù),第一個參數(shù)是匹配的規(guī)則,第二參數(shù)是用來替換的字符串。第一個參數(shù),可以是字符串,也可以是正則表達(dá)式。

字符串就不多說了,這里只說是正則表達(dá)式的情況,replace會根據(jù)正則表達(dá)式去匹配對應(yīng)的結(jié)果,然后將其替換成第二參數(shù):

// 正則表達(dá)式不帶修飾符g
console.log("abc1234".replace(/[a-z]/, "0"))
// 正則表達(dá)式帶修飾符g
console.log("abc1234".replace(/[a-z]/g, "0"))


輸出結(jié)果可以看出,在不加修飾符g的情況下,字符串的repalce方法不會全局檢索替換,而只是替換了第一次。在全局匹配模式下,replace方法會把所有的匹配結(jié)果全局替換成第二個參數(shù)對應(yīng)的字符串。

前文說子表達(dá)式的時候說到,正則表達(dá)式會把匹配結(jié)果存放在類似1,2$1,$2的里面,在這里便可以用到$1,$2了。用法就是,在repealce()方法的第二個參數(shù)字符串中,$1,$2……不再是普通的字符串,而是有著特殊一樣的標(biāo)識符,對應(yīng)的值就是正則表達(dá)式每一個子表達(dá)式匹配到的結(jié)果:

// 定義一個匹配一個abc字符后面跟著一個數(shù)字的正則表達(dá)式
// 并將匹配結(jié)果替換成該子表達(dá)式的結(jié)果
console.log("abc1234".replace(/abc(d)/g, "$1")) // 1234

該替換方法,最終將abc1替換成了第一個子表達(dá)式匹配的結(jié)果1,所以最終結(jié)果是1234。

repalce()方法的第二次參數(shù),不僅可以是字符串,還可以是一個函數(shù),如果是函數(shù)則對每一次的匹配結(jié)果調(diào)用該函數(shù)。該函數(shù)必須返回一個字符串,如果沒有reutrn語句,則是跟正常函數(shù)一樣默認(rèn)返回undefined。如果返回的不是字符串類型,會將其轉(zhuǎn)換成字符串類型:

console.log("abc1234".replace(/abc(d)/g, function(){ 
    return "hello"
}))
// 打印結(jié)果為hello234

從結(jié)果可以看出,將匹配到的字符串a(chǎn)bc1替換成了hello字符串。

同時,該函數(shù)有多個參數(shù),第一個參數(shù)是當(dāng)前匹配到的結(jié)果,第二個參數(shù)開始往后是子表達(dá)式匹配到的結(jié)果,可以有0-n個。再后面一個參數(shù)當(dāng)前匹配結(jié)果在原字符串中的下標(biāo),最后一個參數(shù)原字符串:

"abc1234".replace(/abc(d)(d)/g, function(a,b,c,d,f){
    console.log(a,b,c,d,f)
})
// 打印結(jié)果為 abc12 1 2 0 abc1234

可以看到打印的結(jié)果abc12是正則匹配到的結(jié)果,1是第一個子表達(dá)式(d)匹配的結(jié)果,2是第二個子表達(dá)式(d)匹配到的結(jié)果,0是匹配結(jié)果字符串在原字符串中的下標(biāo),abc1234是原字符串。再看下匹配到多次結(jié)果的情況:

"abc1234abc567".replace(/abc(d)(d)/g, function(a,b,c,d,f){ 
    console.log(a,b,c,d,f)
})
// 下面是打印結(jié)果
abc12 1 2 0 abc1234abc567
abc56 5 6 7 abc1234abc567

對于有多次匹配結(jié)果的情況,會多次調(diào)用該函數(shù)。

? (3) search()方法查找匹配結(jié)果在原字符串中的位置。接收一個字符串或者正則表達(dá)式作為查詢參數(shù)。最終返回查詢到的下標(biāo),沒有查詢到則返回-1。

// 參數(shù)為字符串時
console.log("abcd".search("d")) // 3

// 參數(shù)為正則表達(dá)式
console.log("abcd".search(/d/)) // 3

上面演示了簡單的查找,對于簡單的查找,完全是可以使用字符串的indexOf()方法,查找結(jié)果都是一樣的。

console.log("abcd".indexOf("d")) // 3

需要注意的地方就是:1.該方法不會進(jìn)行全局查找,即會忽略修飾符g,一旦匹配到結(jié)果即返回下標(biāo); 2.會忽略正則表達(dá)式的lastIndex屬性,即每次查找都從字符串開始位置重新開始。

var str = "abcddadd"
// 只返回了第一個d字符的洗標(biāo),忽略修飾符g
console.log(str.search(/d/g)) // 依舊輸出了3

// 第二次調(diào)用,依舊輸出3,即忽略了lastIndex屬性
console.log(str.search(/d/g))

? (4) split()方法: 用于字符串分割,接收一個用于分割字符串的字符串或者正則表達(dá)式作為參數(shù),第二個參數(shù)為可選的指定返回分割后的數(shù)組長度。

// 第一個參數(shù)為""時, 將按字符分割字符串
// 這在我們需要把字符串作為組數(shù)處理時非常有用
"asdfg".split("") // ["a", "s", "d", "f", "g"]
// 可以接收第二參數(shù),作為返回后的數(shù)組長度
"asdfg".split("", 3) // ["a", "s", "d"]
// 以字符串s進(jìn)行跟個
"asdfg".split("s") // ["a", "dfg"]
// 以正則表達(dá)式匹配結(jié)果進(jìn)行分割
"asdfg".split(/s/) // ["a", "dfg"]

比如下面,一個簡易版的解析url中鍵值對參數(shù)

/*
 * 簡易解析url中鍵值對參數(shù)
 * @param url { String } 待解析的url
 * @return { key1: 1, key2: 2} 返回解析后的鍵值對的對象
 */
const parseQueryString = url => {
    if (!url) throw Error("缺少待解析url")
    let result = {}
    const query = url.split("");)[1]
    query && query.split("&").forEach(e => {
        const parts = e.split("=");
        result[parts[0]] = parts[1];
    })
    return result;
}

parseQueryString("www.baidu.com");) // {ke1: 1, key2: 2}

那就再扯一下數(shù)組的join()方法吧,可以理解為字符串split()方法的反作用方法。該方法用于將數(shù)組轉(zhuǎn)換成字符串,接收一個參數(shù),作為拼接符,默認(rèn)是英文逗號:

[1,2,3,4,5].join() // "1,2,3,4,5" // 默認(rèn)逗號拼接
[1,2,3,4,5].join("a") // "1a2a3a4a5" // 自定義用字符a拼接



文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/7013.html

相關(guān)文章

  • 愣錘筆記】MVVM時代下仍需掌握的DOM - 基礎(chǔ)篇

    摘要:然而,操作作為前端的基礎(chǔ),自誕生以來便左右著我們的頁面效果。不管任何時候,依舊是前端必須掌握且需要投入一定時間研究的基礎(chǔ)。不能只停留在事件的操作或者只是掌握那幾個最常見的。在當(dāng)前MVVM大行其道的環(huán)境下提到DOM一詞,很多人可能會感到有些詫異。這種差詫異或許來自于類似都什么年底了還操作DOM啊的聲音!說的沒錯,MVVM時代,虛擬dom東征西戰(zhàn),一枝獨秀,著實不可否認(rèn)其強大的威力。 然而,DO...

    callmewhy 評論0 收藏0
  • 分享AI有道干貨 | 126 篇 AI 原創(chuàng)文章精選(ML、DL、資源、教程)

    摘要:值得一提的是每篇文章都是我用心整理的,編者一貫堅持使用通俗形象的語言給我的讀者朋友們講解機器學(xué)習(xí)深度學(xué)習(xí)的各個知識點。今天,紅色石頭特此將以前所有的原創(chuàng)文章整理出來,組成一個比較合理完整的機器學(xué)習(xí)深度學(xué)習(xí)的學(xué)習(xí)路線圖,希望能夠幫助到大家。 一年多來,公眾號【AI有道】已經(jīng)發(fā)布了 140+ 的原創(chuàng)文章了。內(nèi)容涉及林軒田機器學(xué)習(xí)課程筆記、吳恩達(dá) deeplearning.ai 課程筆記、機...

    jimhs 評論0 收藏0
  • 7月份前端資源分享

    摘要:更多資源請文章轉(zhuǎn)自月份前端資源分享的作用數(shù)組元素隨機化排序算法實現(xiàn)學(xué)習(xí)筆記數(shù)組隨機排序個變態(tài)題解析上個變態(tài)題解析下中的數(shù)字前端開發(fā)筆記本過目不忘正則表達(dá)式聊一聊前端存儲那些事兒一鍵分享到各種寫給剛?cè)腴T的前端工程師的前后端交互指南物聯(lián)網(wǎng)世界的 更多資源請Star:https://github.com/maidishike... 文章轉(zhuǎn)自:https://github.com/jsfr...

    pingan8787 評論0 收藏0
  • 讓人相見恨晚的vim插件:模糊查找神器LeaderF

    摘要:是什么是一個用寫的插件,可以在成千上萬數(shù)十萬個文件中,通過模糊查找的方式,快速找到目標(biāo)文件。它還有很多衍生功能快速打開或定位某個最近使用的文件包括函數(shù)類變量等命令歷史文件中的某一行的等等。友情鏈接,也許是最好的模糊查詢插件 提到vim的模糊查找插件,很多人第一反應(yīng)是ctrlp.vim,ctrlp知名度很高,但跟其它的同類插件相比,它的唯一優(yōu)點是用vimL編寫(這讓它的性能是所有同類插件...

    Near_Li 評論0 收藏0

發(fā)表評論

0條評論

wangbjun

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<