正則表達(dá)式中?=、?!、?<=、?<!、?:的理解與應(yīng)用舉例
一、?=、?!、?<=、?<!、?:的解釋
1. 先看一下比較官方的解釋
(?=pattern)
:正向先行斷言,表示匹配位置后面必須緊跟著滿(mǎn)足pattern
的字符串,但不包括這個(gè)字符串在匹配結(jié)果中。(?!pattern)
:負(fù)向先行斷言,表示匹配位置后面不能緊跟著滿(mǎn)足pattern
的字符串,也不包括這個(gè)字符串在匹配結(jié)果中。(?<=pattern)
:正向后行斷言,表示匹配位置前面必須是滿(mǎn)足pattern
的字符串,但不包括這個(gè)字符串在匹配結(jié)果中。(?<!pattern)
:負(fù)向后行斷言,表示匹配位置前面不能是滿(mǎn)足pattern
的字符串,也不包括這個(gè)字符串在匹配結(jié)果中。(?:pattern)
:非捕獲型分組,表示將pattern
包含在一個(gè)分組中,但不把這個(gè)分組的匹配結(jié)果保存到分組編號(hào)中。這個(gè)分組通常用于表示可選的或重復(fù)的子表達(dá)式,或者是限制量詞的作用范圍,而不需要把它們的匹配結(jié)果單獨(dú)提取出來(lái)。
2. 再看一下比較通俗易懂的解釋?zhuān)?/h3>
- RegExp1(?=RegExp2) 匹配后面是RegExp2 的 RegExp1
- RegExp1(?!RegExp2) 匹配后面不是RegExp2 的 RegExp1
- (?<=RegExp2)RegExp1 匹配前面是RegExp2 的 RegExp1
- (?<!RegExp2)RegExp1 匹配前面不是RegExp2 的 RegExp1
- (?:RegExp) 這個(gè)等下單獨(dú)解釋?zhuān)c上面的不太一樣
是不是有點(diǎn)明白了,其實(shí)?=、?!、?<=、?<!的意思可以理解為 if 判斷,即只有先通過(guò)它們(RegExp2)的判斷之后,才可以獲取到正則(RegExp1)的匹配結(jié)果。
3. 零寬度斷言
?=、?!、?<=、?<!其實(shí)就是正則表達(dá)式中的零寬度斷言,以上面的舉例來(lái)解釋↓
RegExp2匹配到的內(nèi)容是不會(huì)返回的,也不會(huì)消耗匹配到的字符,只會(huì)返回RegExp1的匹配結(jié)果,這就是零寬度斷言,零寬度斷言在正則表達(dá)式中非常有用,因?yàn)樗鼈兛梢栽诓桓淖兤ヅ浣Y(jié)果的情況下,對(duì)匹配位置前后的內(nèi)容進(jìn)行限制或判斷。
4. ?: 的解釋
(?:) 并不是零寬度斷言,而是非捕獲組,它跟普通的括號(hào) () 的區(qū)別在于,它不會(huì)保存匹配到的內(nèi)容,但是它仍然會(huì)消耗字符并返回匹配內(nèi)容,只是不會(huì)保存匹配結(jié)果。
- ()表示捕獲分組,它會(huì)把匹配到的內(nèi)容保存到內(nèi)存中,開(kāi)發(fā)者可以使用$n(n是一個(gè)數(shù)字)來(lái)代表第n個(gè)()中匹配到的內(nèi)容
- (?:)表示非捕獲組,它匹配的內(nèi)容不會(huì)被保存,所以無(wú)法使用$n獲取,但也因?yàn)闆](méi)有被保存所以節(jié)省了一部分內(nèi)存空間
二、舉例
?=
'我喜歡蘋(píng)果'.replace(/我喜歡(?=蘋(píng)果)/,'我討厭') // 匹配 我喜歡蘋(píng)果 中的 我喜歡 并替換為 我討厭,因?yàn)槭橇銓挾葦嘌运圆话O(píng)果,故結(jié)果為 我討厭蘋(píng)果 '我喜歡橘子'.replace(/我喜歡(?=蘋(píng)果)/,'我討厭') // 我喜歡后面不是蘋(píng)果,所以這里正則未通過(guò),匹配不到任何內(nèi)容,故結(jié)果仍為 我喜歡橘子
?!
'我喜歡蘋(píng)果'.replace(/我喜歡(?!蘋(píng)果)/,'我討厭') // 匹配后面不是蘋(píng)果的我喜歡,正則未通過(guò),故結(jié)果仍為 我喜歡蘋(píng)果 '我喜歡橘子'.replace(/我喜歡(?!蘋(píng)果)/,'我討厭') // 正則通過(guò),匹配到 我喜歡 進(jìn)行替換,因?yàn)槭橇銓挾葦嘌运蚤僮硬辉谄ヅ浣Y(jié)果中,故結(jié)果為 我討厭橘子
?<=
'我喜歡蘋(píng)果'.replace(/(?<=我喜歡)蘋(píng)果/,'西紅柿') // 匹配到 蘋(píng)果 ,故結(jié)果為 我喜歡西紅柿 '我喜歡橘子'.replace(/(?<=我喜歡)蘋(píng)果/,'西紅柿') // 匹配不通過(guò),故結(jié)果仍為 我喜歡橘子
?<
'我討厭蘋(píng)果'.replace(/(?<!我喜歡)蘋(píng)果/,'西紅柿') // 匹配到 蘋(píng)果 ,故結(jié)果為 我討厭西紅柿 '我喜歡蘋(píng)果'.replace(/(?<!我喜歡)蘋(píng)果/,'西紅柿') // 匹配不通過(guò),故結(jié)果仍為 我喜歡蘋(píng)果
?:
'hello world'.replace(/(?:hello) (world)/,'$1') // 匹配內(nèi)容為hello world,但是hello并沒(méi)有被保存,因此$1取的是world,故結(jié)果為world
三、特殊情況
正則平時(shí)我們很少會(huì)自己寫(xiě),一般都是復(fù)制別人的~~~(別人的才是最好的)。然后就經(jīng)??吹揭环N寫(xiě)法,比如:
/(?=.*[A-Z])[A-Za-z]{5,10}/
這時(shí)候可能有些人就想,咦,(?=)不都是符合條件后匹配它前面的內(nèi)容嗎?這里為什么能放在開(kāi)頭 呢,他前面沒(méi)內(nèi)容?。科鋵?shí)大家可以這么理解,當(dāng)(?=)前面沒(méi)有內(nèi)容,或者說(shuō)(?=)被放在正則開(kāi)頭使用時(shí),(?=)的作用就相當(dāng)于檢索全部?jī)?nèi)容是否符合它的要求,如果不符合也就沒(méi)必要繼續(xù)向后匹配了,這就很像if判斷,只有當(dāng)條件為true時(shí),才能執(zhí)行后面的內(nèi)容。
所以這里的正則意為:先檢查內(nèi)容中是否至少包含一個(gè)大寫(xiě)字母,如果有,則繼續(xù)檢查并匹配5~10個(gè)大小寫(xiě)字母,將這5~10個(gè)大小寫(xiě)字母作為結(jié)果返回。
四、實(shí)例應(yīng)用
姓名脫敏(添加*號(hào))
'李小龍'.replace(/(?<=[\u4e00-\u9fa5])[\u4e00-\u9fa5]/g, '*') // 李**
手機(jī)號(hào)/銀行賬號(hào)脫敏
'13912345678'.replace(/(?<=\d{3})\d(?=\d{3})/g, '*') // 139*****678
強(qiáng)密碼規(guī)則校驗(yàn)
// 密碼不能為空,8-30位,至少包含一個(gè)大寫(xiě)字母、小寫(xiě)字母、數(shù)字、特殊字符 /^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[\W_])(?!.*[\u4e00-\u9fa5])(?!\s)[a-zA-Z0-9\W_]{8,30}$/
“?”的幾種用法
- “?”元字符規(guī)定其前導(dǎo)對(duì)象必須在目標(biāo)對(duì)象中連續(xù)出現(xiàn)零次或一次。
- 當(dāng)該字符緊跟在任何一個(gè)其他限制符(*,+,?,{n},{n,},{n,m})后面時(shí),匹配模式是非貪婪的。非貪婪模式盡可能少的匹配所搜索的字符串,而默認(rèn)的貪婪模式則盡可能多的匹配所搜索的字符串。例如,對(duì)于字符串“oooo”,“o+?”將匹配單個(gè)“o”,而“o+”將匹配所有“o”。
- (?:pattern) ——匹配pattern但不獲取匹配結(jié)果,也就是說(shuō)這是一個(gè)非獲取匹配,不進(jìn)行存儲(chǔ)供以后使用。這在使用或字符“(|)”來(lái)組合一個(gè)模式的各個(gè)部分是很有用。例如“industr(?:y|ies)”就是一個(gè)比“industry|industries”更簡(jiǎn)略的表達(dá)式。
- (?=pattern)——正向肯定預(yù)查,在任何匹配pattern的字符串開(kāi)始處匹配查找字符串。這是一個(gè)非獲取匹配,也就是說(shuō),該匹配不需要獲取供以后使用。例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。預(yù)查不消耗字符,也就是說(shuō),在一個(gè)匹配發(fā)生后,在最后一次匹配之后立即開(kāi)始下一次匹配的搜索,而不是從包含預(yù)查的字符之后開(kāi)始。
- (?!pattern)——正向否定預(yù)查,在任何不匹配pattern的字符串開(kāi)始處匹配查找字符串。這是一個(gè)非獲取匹配,也就是說(shuō),該匹配不需要獲取供以后使用。例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中的“Windows”。預(yù)查不消耗字符,也就是說(shuō),在一個(gè)匹配發(fā)生后,在最后一次匹配之后立即開(kāi)始下一次匹配的搜索,而不是從包含預(yù)查的字符之后開(kāi)始
- (?<=pattern)——反向肯定預(yù)查,與正向肯定預(yù)查類(lèi)擬,只是方向相反。例如,“(?<=95|98|NT|2000)Windows”能匹配“2000Windows”中的“Windows”,但不能匹配“3.1Windows”中的“Windows”。
- (?<!pattern)——反向否定預(yù)查,與正向否定預(yù)查類(lèi)擬,只是方向相反。例如“(?<!95|98|NT|2000)Windows”能匹配“3.1Windows”中的“Windows”,但不能匹配“2000Windows”中的“Windows”。
- (?i)——該表達(dá)式右邊的字符忽略大小寫(xiě)
- (?-i)——該表達(dá)式右邊的字符區(qū)分大小寫(xiě)
- (?i:x)——x 忽略大小寫(xiě)
- (?-i:x)——x 區(qū)分大小寫(xiě)
- ?和懶惰匹配——盡可能少的匹配,例如:源字符串str=“dxxddxxd”中,d\w*?會(huì)匹配 dx,而d\w*?d會(huì)匹配 dxxd。
總結(jié)
到此這篇關(guān)于正則表達(dá)式中?=、?!、?<=、?<!、?:的理解與應(yīng)用舉例的文章就介紹到這了,更多相關(guān)正則表達(dá)式?=、?!、?<=、?<!、?:內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JS和C#實(shí)現(xiàn)的兩個(gè)正則替換功能示例分析
這篇文章主要介紹了JS和C#實(shí)現(xiàn)的兩個(gè)正則替換功能,結(jié)合具體實(shí)例形式分析了js與C#進(jìn)行字符串正則替換的相關(guān)實(shí)現(xiàn)方法與注意事項(xiàng),需要的朋友可以參考下2017-06-06python 正則表達(dá)式語(yǔ)法學(xué)習(xí)筆記
正則表達(dá)式是一個(gè)特殊的字符序列,它能幫助你方便的檢查一個(gè)字符串是否與某種模式匹配。這篇文章主要介紹了python 正則表達(dá)式語(yǔ)法記錄,需要的朋友可以參考下2020-02-02JavaScript 表單驗(yàn)證正則表達(dá)式大全[推薦]
JavaScript驗(yàn)證正則表達(dá)式大全,搜集最全的JavaScript驗(yàn)證正則表達(dá)式,開(kāi)始查看吧,這里的都是正則表達(dá)式的例子2009-08-08正則匹配密碼只能是數(shù)字和字母組合字符串功能【php與js實(shí)現(xiàn)】
這篇文章主要介紹了正則匹配密碼只能是數(shù)字和字母組合字符串功能,涉及針對(duì)字符、數(shù)字等正則操作相關(guān)技巧,并給出了php與js實(shí)現(xiàn)示例,需要的朋友可以參考下2017-01-01詳解表單驗(yàn)證正則表達(dá)式實(shí)例(推薦)
這篇文章主要介紹了詳解表單驗(yàn)證正則表達(dá)式實(shí)例(推薦)的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,特此分享到腳本之家平臺(tái)供大家參考2016-05-05在nest.js中通過(guò)正則表達(dá)式正確設(shè)置驗(yàn)證的方法
這篇文章主要介紹了在nest.js中通過(guò)正則表達(dá)式正確設(shè)置驗(yàn)證的方法,文末給大家補(bǔ)充介紹了js正則表達(dá)式驗(yàn)證大全,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒借鑒價(jià)值,需要的朋友可以參考下2022-03-03js 正則表達(dá)式學(xué)習(xí)筆記之匹配字符串
這篇文章主要介紹了js 正則表達(dá)式匹配字符串,需要的朋友可以參考下2014-05-05用正則表達(dá)式匹配字符串中漢字及中文標(biāo)點(diǎn)符號(hào)
正則表達(dá)式通常用于判斷某一個(gè)字符串是否符合或滿(mǎn)足某一種格式,下面這篇文章主要給大家介紹了關(guān)于如何使用正則表達(dá)式匹配字符串中漢字及中文標(biāo)點(diǎn)符號(hào)的相關(guān)資料,需要的朋友可以參考下2022-07-07自動(dòng)識(shí)別HTML的標(biāo)記 替換連接
自動(dòng)識(shí)別HTML的標(biāo)記 替換連接...2006-07-07