摘要:對(duì)前端來(lái)說(shuō),使用的場(chǎng)景不多,但是像微信端的對(duì)話系統(tǒng)的表情包,就使用到了一個(gè)特定的規(guī)則。我是一個(gè)前端,工作年了,現(xiàn)在失業(yè),想進(jìn)入騰訊工作,這是我的聯(lián)系方式這個(gè)正則雖
我發(fā)現(xiàn)有個(gè)別字符被這個(gè)編輯器給刷掉了,但是灰色區(qū)域顯示正常,以灰色區(qū)域代碼為準(zhǔn)
什么玩意?在我剛開(kāi)始學(xué)習(xí)編程的時(shí)候,就聽(tīng)過(guò)正則了,也聽(tīng)說(shuō)正則很牛逼,懂正則的更牛逼。但是苦于沒(méi)有人指點(diǎn),也沒(méi)有使用正則的場(chǎng)景,自己看教程又懵逼,直到現(xiàn)在,才發(fā)現(xiàn)了入門的訣竅。
在不同的編程語(yǔ)言中,正則表達(dá)式的寫法會(huì)有所不同,這里我們討論的是JavaScript正則寫法。
學(xué)習(xí)正則,不要憑空想象,要使用開(kāi)發(fā)工具去測(cè)試,推薦你使用在線正則測(cè)試網(wǎng)站:https://regex101.com,或者使用瀏覽器控制臺(tái)。
最簡(jiǎn)單的正則正則在自然語(yǔ)言處理中廣泛運(yùn)用到,對(duì)前端開(kāi)發(fā)者來(lái)說(shuō),最常見(jiàn)的正則是表單上的一些驗(yàn)證。如果你不熟悉正則,在寫表單的時(shí)候,是從網(wǎng)上直接搜索某某正則的寫法,然后copy過(guò)來(lái)。
但是,在你看完這篇文章之后,我希望你可以直接寫出一些簡(jiǎn)單的正則,不再需要百度了。
現(xiàn)在介紹一種最簡(jiǎn)單的正則(匹配指定的文本):
下面是一段美文,我們現(xiàn)在想把里面的某個(gè)字,比如(的),匹配出來(lái)。
var s = "前世茫茫人海的擦肩,種了今生的遇見(jiàn),在花海的某一朵間,是你最美的笑顏。繁花三千,只為一人留戀,幾度春秋,只等你花開(kāi)的一面。多少來(lái)來(lái)回回,夢(mèng)里若隱若現(xiàn),舉著思念的酒盞,輕酌夜色微涼,讓回憶的美好舞翩翩。擱淺了時(shí)光,靜默緣分的一端,遠(yuǎn)處的風(fēng)景,依然是你微笑的眉眼。" s.match(/的/g)
我們使用到了match方法來(lái)做匹配,來(lái)分析一下這個(gè)寫法,s表示字符串,g表示全局匹配,如果去掉g,只能匹配出來(lái)第一個(gè)(的)。
是不是最簡(jiǎn)單的正則?你需要匹配什么內(nèi)容,就直接在//之間寫這個(gè)字符,然后正則系統(tǒng)會(huì)自動(dòng)從字符串去查找。
可能這樣說(shuō)不是很直觀,我奉獻(xiàn)一張101的截圖,特別關(guān)注紅框部分,最上邊是正則的輸入框,下面是字符串,右邊是匹配出來(lái)的字符:
上面的例子中,使用到了match(),可以匹配出來(lái)字符,并且返回值是一個(gè)數(shù)組。還有一個(gè)常用的方法是test(),test的返回值是bool類型,通常用來(lái)寫在if語(yǔ)句中判斷一個(gè)字符串是否滿足正則表達(dá)式,在表單驗(yàn)證中經(jīng)常用到。還有一個(gè)常用的方法是replace(),replace和match比較像,都能匹配出字符,但是replace還有第二個(gè)參數(shù)可以做字符替換。
下面我們會(huì)講到三個(gè)方法的具體使用場(chǎng)景。往下看!
正則有各種各樣的符號(hào),一般很難背下來(lái),但是常用的符號(hào)多練習(xí)幾遍,印象就會(huì)深刻。
我們用實(shí)際的例子來(lái)分析test()以及正則的實(shí)現(xiàn),以注冊(cè)表單為例:
test()和match()寫法剛好反過(guò)來(lái),test是正則寫在前面,字符串寫到函數(shù)的參數(shù)中。
看到這樣一道題目,你首先要思考2個(gè)字——“規(guī)則”,賬號(hào)是主體,賬號(hào)的規(guī)則是只能是數(shù)字,那么就是說(shuō)輸入非數(shù)字就不能匹配。
了解了規(guī)則之后,就很簡(jiǎn)單了,正則提供了默認(rèn)匹配數(shù)字的字符,d或者是[0-9],那么是不是直接/d/.test("123")就行了呢?當(dāng)然不是,d表示是數(shù)字,你還需要加上一個(gè)特殊字符,表示匹配所有的數(shù)字,因?yàn)橐粋€(gè)字符串有N個(gè)數(shù)字,全部都要匹配成功。
這里我使用的是+,加號(hào)表示至少匹配一次數(shù)字,比如123,如果使用d,就只能一個(gè)個(gè)匹配出來(lái)[1,2,3],這需要在match方法中使用,在test方法中,必須匹配整個(gè)字符串是否符合正則。改成d+之后,匹配的是整個(gè)字符串中的數(shù)字,是不是離我們的最終結(jié)果很接近了。
上面的操作似乎已經(jīng)可以匹配出數(shù)字了,但是記住,test()方法中,如果你要驗(yàn)證整個(gè)字符串只能是數(shù)字,必須加上正則的開(kāi)始符號(hào)^和結(jié)束符號(hào)$,表示的是從字符串"123"開(kāi)頭匹配到結(jié)尾都必須滿足數(shù)字,如果中間插入其他字符"1kk2什么3",就匹配失敗。所以最終的正則寫法是 /^d+$/,或者是/^d+$/g,這里的g可加可不加。
var user = "123" //可以把123改成任意字符來(lái)測(cè)試。 if (/^d+$/g.test(user)) {} //寫法1 if(true){} if (/^[0-9]+$/g.test(user)) {} //寫法2 if(true){}場(chǎng)景2:賬號(hào)只能是字母
數(shù)字匹配完了,換成字母會(huì)不會(huì)呢?只要把d或[0-9]改成字母的正則就行了。字母包含大小寫,所以使用[a-zA-Z]。如果去掉^和$,那么僅僅是匹配user字符串中是否包含字母,使用indexOf()或者includes()代替。
var user = "hyy" //可以把hyy改成任意字符來(lái)測(cè)試。 if (/^[a-zA-Z]+$/g.test(user)) {} //if(true){}場(chǎng)景3:賬號(hào)只能是字母開(kāi)頭,并且字母和數(shù)字的組合,長(zhǎng)度范圍是6-10。
單打了2輪,不夠爽,來(lái)一套組合拳。上面學(xué)習(xí)了 ^ $ [0-9] [a-zA-Z] + 這幾個(gè)正則符號(hào)的使用,一定要記下來(lái),很常用的。這組合拳似乎有點(diǎn)復(fù)雜,不過(guò)不怕,遇到這種問(wèn)題,我們第一步還是提取規(guī)則:
字母開(kāi)頭;
字母和數(shù)字組合;
長(zhǎng)度6-10。
1、你腦子里要想著 /^what?$/.test(user) 的結(jié)構(gòu)。
2、字母開(kāi)頭,那么就是第一個(gè)字符必須是字母。你需要學(xué)習(xí)一個(gè)新的正則,大括號(hào){n,m},x{1}表示匹配前面的字符1次,x{2}表示匹配2次符合x的字符,還可以寫成x{1,3},表示匹配符合x正則的符合最少1次,最多3次。說(shuō)這段話你一下子理解不了,就跳過(guò)。我們只看{1}這種情況。所以,現(xiàn)在加上字母開(kāi)頭這條規(guī)則之后,正則變成了 /^[a-zA-Z]{1}}/,注意,我暫時(shí)沒(méi)有寫結(jié)束符號(hào),最后再加上。
/^[a-zA-Z]{1}}/
3、字母和數(shù)字組合,我們是不是要寫成[a-zA-Z]d呢?其實(shí)還有一個(gè)更好的辦法,你又學(xué)到了一個(gè)新的正則w,w和([a-zA-Z]|d)相同,都表示字母和數(shù)字的組合。順便再講講 () 和 | 這2個(gè)正則的含義。在正則中,()表示一個(gè)group,也就是組,|表示或,所以([a-zA-Z]|d)的含義就是字母或者數(shù)字,再使用()括起來(lái),形成了一個(gè)正則組。覺(jué)得括號(hào)復(fù)雜的話,使用w就行了。
/^[a-zA-Z]{1}w/
4、終于快搞定了,最后一條規(guī)則,長(zhǎng)度6-10,如果你不想使用正則,那么長(zhǎng)度也可以根據(jù)字符串的length來(lái)判斷,這樣的話,上面的正則可以加上結(jié)束符號(hào)$直接使用了。w后面我悄悄加了個(gè)+,因?yàn)橐ヅ浜竺娴乃凶帜负蛿?shù)字至少一次,然后再寫$結(jié)束:
if(/^[a-zA-Z]{1}w+$/g.test("Hyy123") && "Hyy123".length > 5 && "Hyy123".length < 11){}
但是既然學(xué)習(xí)正則,那就用正則的方式去解決,其實(shí)更加簡(jiǎn)單。
利用上面學(xué)習(xí)的大括號(hào){},我們可以很容易實(shí)現(xiàn)長(zhǎng)度控制。直接給你看最終形態(tài):
if(/^[a-zA-Z]{1}w{5,9}$/g.test("Hyy123")){} //true
這個(gè)最終形態(tài)的正則可以拆分成幾部分來(lái)看:
^:開(kāi)頭 [a-zA-Z]{1}:第一個(gè)字符匹配一次,且只能是字母 w{5,9}:后面的字符是字母或者數(shù)字的組合,且長(zhǎng)度是6-10,因?yàn)榈谝粋€(gè)字符占了一個(gè)長(zhǎng)度,所以這里匹配的是5-9的長(zhǎng)度 $:結(jié)束場(chǎng)景4:密碼只能是6位數(shù)字。
這個(gè)就簡(jiǎn)單多了。規(guī)則首先是數(shù)字,然后長(zhǎng)度是6。最后的g可要可不要。
/^d{6}$/match()
test()通常用來(lái)驗(yàn)證字符串是否符合某個(gè)規(guī)則,而match()是從字符串里面提取符合某規(guī)則的字符。對(duì)前端來(lái)說(shuō),match使用的場(chǎng)景不多,但是像微信端app的對(duì)話系統(tǒng)的表情包,就使用到了一個(gè)特定的規(guī)則。
你在給一個(gè)朋友發(fā)微信的時(shí)候,一般是直接點(diǎn)擊某個(gè)表情,然后發(fā)送,但是其實(shí)還可以輸入一些字符組合,然后發(fā)送后,在聊天界面,微信系統(tǒng)會(huì)自動(dòng)匹配出來(lái)某個(gè)表情。這里我猜測(cè)就是用match做的字符串處理,又或許有什么我不知道的高深技術(shù)吧。
我用一個(gè)組合拳的例子介紹一下match的使用場(chǎng)景:
1、有這樣一段文字:
我是一個(gè)前端,工作1年了,現(xiàn)在失業(yè),想進(jìn)入騰訊工作,這是我的聯(lián)系方式:15527578846
2、假設(shè)你來(lái)應(yīng)聘前端工程師,我是面試官,我給你提這么幾個(gè)需求,從這段話中,提取聯(lián)系方式,工作年限,你該怎么辦??
3、有時(shí)候前端也會(huì)碰到類似的需求,第一步是分析規(guī)則:
聯(lián)系方式:聯(lián)系方式可能有很多種情況,比如手機(jī)號(hào)、微信、qq、座機(jī)號(hào)等,好吧,這樣一看的確非常復(fù)雜,那么我們只考慮手機(jī)號(hào)的情況。
工作年限:工作年限是阿拉伯?dāng)?shù)字。
4、考慮用什么方法去匹配,test還是match?這里一看就是用match,先分析第一個(gè),提取聯(lián)系方式,或者說(shuō)提取手機(jī)號(hào)。手機(jī)號(hào)本身也有特定的規(guī)則:
開(kāi)頭是1; 長(zhǎng)度11; 第2位是3或5或7; 第3位到第11位是0到9的數(shù)字。
或許還有更加詳細(xì)的手機(jī)號(hào)規(guī)則,你可以網(wǎng)上查一下手機(jī)號(hào)的組成規(guī)則。
5、現(xiàn)在開(kāi)始用正則匹配出來(lái)吧,不要怕,很簡(jiǎn)單的。看第一條,開(kāi)頭是1,啥,開(kāi)頭,你是不是又想到了/^1/。對(duì)不起,你這樣寫就錯(cuò)了。因?yàn)樽址拈_(kāi)頭是 "我",所以你換一下寫法就對(duì)了。
/1/
6、長(zhǎng)度是11位,這個(gè)很重要,但后面才匹配長(zhǎng)度,先看第二位數(shù)字的規(guī)則,3、5、7,用正則組的寫法就是 (3|5|7)。
/1(3|5|7){1}/ //這里再加個(gè){1}表示匹配前面括號(hào)里的規(guī)則1次。這樣就能匹配到字符串里的15了。
7、第3到第11位是0-9的數(shù)字,那么就是d{9},因?yàn)楹竺孢€有9位數(shù)字,所以匹配9次即可。
/1(3|5|7){1}d{9}/ //匹配出來(lái)就是15527578846
8、看看完整的寫法,match匹配出來(lái)的是一個(gè)數(shù)組,
var s = "我是一個(gè)前端,工作1年了,現(xiàn)在失業(yè),想進(jìn)入騰訊工作,這是我的聯(lián)系方式:15527578846" //加g匹配完整的正則 s.match(/1(3|5|7){1}d{9}/g) // ["15527578846"] //不加g匹配完整的正則的同時(shí),還將()里面的小正則也匹配出來(lái)。 s.match(/1(3|5|7){1}d{9}/) //["15527578846", "5", index: 35, input: "我是一個(gè)前端,工作1年了,現(xiàn)在失業(yè),想進(jìn)入騰訊工作,這是我的聯(lián)系方式:15527578846"]
9、這個(gè)正則雖然提取出來(lái)了手機(jī)號(hào),但是并不完善,更加精確的匹配需要判斷開(kāi)頭和結(jié)尾不能再跟著其他數(shù)字,比如991552757884699,這樣仍舊會(huì)把99中間的11位數(shù)字提取出來(lái)。當(dāng)然,這不屬于當(dāng)前場(chǎng)景考慮的問(wèn)題了。
10、分析第二個(gè),工作年限,工作年限有個(gè)特點(diǎn),就是他是數(shù)字,并且后面一定跟著“年”,前面跟著“工作”,這樣一來(lái)規(guī)則就很簡(jiǎn)單了。正則里面的問(wèn)號(hào) ? 表示問(wèn)號(hào)前面的規(guī)則匹配0次或者1次。意思就是如果"工作"不存在,正則也成立。比如原句子是“工作1年”,變成“1年”。同樣可以匹配。
s.match(/(工作)?(d{1,2})年/) //(d{1,2})年限最少1次,最多2次,我不信你工作了100年。 // ["工作1年", "工作", "1", index: 7, input: "我是一個(gè)前端,工作1年了,現(xiàn)在失業(yè),想進(jìn)入騰訊工作,這是我的聯(lián)系方式:15527578846"] s.match(/(工作)?(d{1,2})年/)[2] //目標(biāo)結(jié)果 1replace()
在前端開(kāi)發(fā)中,這個(gè)方法很常用,看這么幾個(gè)場(chǎng)景:
場(chǎng)景1:將字符串里面的逗號(hào)替換成感嘆號(hào)var s = "我是一個(gè)前端,上班1年了,現(xiàn)在失業(yè),想進(jìn)入騰訊工作,這是我的聯(lián)系方式:15527578846" s.replace(/,/g, "!") // "我是一個(gè)前端!上班1年了!現(xiàn)在失業(yè)!想進(jìn)入騰訊工作!這是我的聯(lián)系方式:15527578846"場(chǎng)景2:將手機(jī)號(hào)最后8位替換成 *
1、首先你要使用test判斷是否是手機(jī)號(hào),然后再執(zhí)行替換語(yǔ)句。
2、使用match提取出手機(jī)號(hào)的后8位數(shù)字。
"15527578846".match(/^d{3}((d){8})$/) //["15527578846", "27578846", "7", index: 0, input: "15527578846"] var r = "15527578846".match(/^d{3}((d){8})$/)[1] //"27578846"
3、接著執(zhí)行replace匹配變量r,然后執(zhí)行替換。
"15527578846".match(/^d{3}((d){8})$/) //["15527578846", "27578846", "7", index: 0, input: "15527578846"] var r = "15527578846".match(/^d{3}((d){8})$/)[1] //"27578846" "15527578846".replace(r, "********") // "155********"
4、我們可以將這個(gè)過(guò)程封裝成一個(gè)函數(shù)。
function regexTest(tel) { if(typeof tel !== "string") throw Error("類型不對(duì)!"); tel.match(/^d{3}((d){8})$/); var r = tel.match(/^d{3}((d){8})$/)[1]; return tel.replace(r, "********"); } regexTest("15527578846") // "155********"總結(jié)
本章你所學(xué)到的是正則入門的知識(shí)。掌握這些常用的語(yǔ)法和寫一個(gè)正則的思路,對(duì)于一些簡(jiǎn)單的正則,應(yīng)該能夠自己寫出來(lái)。后面還會(huì)繼續(xù)跟大家分享各種正則需求的實(shí)現(xiàn)思路。
下一章:正則實(shí)戰(zhàn)篇
正則系列文章整理到了github:https://github.com/hyy1115/Re...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/91825.html
摘要:正則正則匹配的是零寬斷言這一塊我還沒(méi)有完成掌握,它的大概意思是,獲取某個(gè)字符或者某些字符前面的正則或者后面的正則。下一章正則表達(dá)式理論鞏固篇正則系列文章整理到了 如果你正則基礎(chǔ)為0,請(qǐng)先看第一篇文章:JavaScript正則表達(dá)式入門心得 實(shí)戰(zhàn)篇 上一章我分享了正則入門的一些體會(huì)以及注意事項(xiàng)。這一章開(kāi)始挑一些常用的比較復(fù)雜一點(diǎn)的需求來(lái)練習(xí)一下。 場(chǎng)景1:驗(yàn)證email是否合法 郵箱種類...
摘要:為此決定自研一個(gè)富文本編輯器。本文,主要介紹如何實(shí)現(xiàn)富文本編輯器,和解決一些不同瀏覽器和設(shè)備之間的。 對(duì)ES6Generator函數(shù)的理解 Generator 函數(shù)是 ES6 提供的一種異步編程解決方案,語(yǔ)法行為與傳統(tǒng)函數(shù)完全不同。 JavaScript 設(shè)計(jì)模式 ② 巧用工廠模式和創(chuàng)建者模式 我為什么把他們兩個(gè)放在一起講?我覺(jué)得這兩個(gè)設(shè)計(jì)模式有相似之處,有時(shí)候會(huì)一個(gè)設(shè)計(jì)模式不能滿...
閱讀 1696·2021-10-14 09:43
閱讀 5859·2021-09-07 10:21
閱讀 1381·2019-08-30 15:56
閱讀 2209·2019-08-30 15:53
閱讀 1298·2019-08-30 15:44
閱讀 2068·2019-08-30 15:44
閱讀 1396·2019-08-29 17:24
閱讀 830·2019-08-29 15:19