「正則」初探正則匹配的魅力
大家好,我是TianTian。
今天要分享的內(nèi)容是正則表達(dá)式Regex。
某天中午正要拿起手機(jī)打把王者榮耀,突然微信來(lái)了條消息!
某位網(wǎng)友來(lái)電,問(wèn)我能不能幫忙看個(gè)字符串匹配的問(wèn)題。
我硬著頭皮答應(yīng)了,可是,我看到題目的時(shí)候。
題目大概需要匹配檢索的是:
- =A12/B14/D14..../H18
- =C12 * D12 * H16...*F19
嗯,我翻開了我多年沒(méi)有碰的正則手冊(cè)。
初探Regex
首先,先簡(jiǎn)單介紹一下:
- 正則表達(dá)式(也稱為regex或regexp)只是一種模式,可用于匹配字符的不同且通常是特定的組合。
我們可以使用這些模式來(lái)檢查和處理字符串,如何檢索呢,我們得知道如何構(gòu)造,創(chuàng)建正則表達(dá)式可能看起來(lái)像這樣:
- let dog;
- rat = /dog/;
- rat = new RegExp("dog");
有了表達(dá)式,那么我們?nèi)绾纹ヅ淠?,?dāng)然正則表達(dá)式有自己的可用方法,也可以在某些字符串方法中使用它們。
例如,.test是可用于正則表達(dá)式的方法。它返回是否在字符串中找到正則表達(dá)式的布爾值:
- let rat = /dog/;
- rat.test('I saw a dog!'); // returns true
- /rat/.test('I saw a dog!'); // returns true
上面兩種調(diào)用.test的方式是等效的:也就是說(shuō),可以使用分配給regexp的變量或直接使用regexp來(lái)調(diào)用它。對(duì)于正則表達(dá)式的任何使用都是如此。重要的是要注意,正則表達(dá)式匹配必須精確,包括任何換行符,大寫字母和空白。例如:
- /dog/.test('I saw some dogs!'); // returns true
- /dog/.test('Meet at the bad og 9'); // returns false
- /dog/.test('Rats and doihs are not friends'); // returns false
看到這里,肯定不理解,為什么要使用它吧,不急,往下看。
特殊字符
特殊字符是用于修改或指定正則表達(dá)式的字符組合的字符。最有用的特殊字符之一是方括號(hào)。方括號(hào)允許您表示目標(biāo)字符串中的字符可以是任意數(shù)量的字符!讓我們看看它們的作用:
- const bt = /b[aeiou]t/;
- bt.test('bat'); // returns true
- bt.test('bet'); // returns true
- bt.test('bit'); // returns true
- bt.test('bot'); // returns true
- bt.test('but'); // returns true
- bt.test('bpt'); // returns false
想想看,括號(hào)里的一切都對(duì)應(yīng)于你要搜索的字符串中的一個(gè)字符。在這個(gè)有用的能力之上,我們可以使用"-"字符來(lái)指定一個(gè)特定的字符范圍!
- const nums = /[0-5]/;
- nums.test('0'); // returns true
- nums.test('3'); // returns true
- nums.test('7'); // returns false
再者,比如,要指定所有的字母,你會(huì)做這樣的事情:
- const letters = /[A-Za-z]/;
- letters.test('M'); // returns true
- letters.test('y'); // returns true
- letters.test('5'); // returns false
另一個(gè)需要記住的特殊字符是 "+"字符。這表明一個(gè)特定的元素可以重復(fù)任何次數(shù)。讓我們看看它的作用。
- const bomb = /boo+m/;
- bomb.test('boom!'); // returns true
- bomb.test('Boom!'); // returns false
- bomb.test('boooooooooooom!'); // returns true
如果你想忽略大小寫怎么辦,可以在后面加個(gè)i。
- const bomb = /boo+m/i;
- bomb.test('boom!'); // returns true
- bomb.test('Boom!'); // returns true
- bomb.test('boooooooooooom!'); // returns true
- bomb.test('BOOOOOOOOOOOOM!'); // returns true
比如我們常見(jiàn)的"?"字符也是一個(gè)有用的特殊字符。這個(gè)字符表示前面的字符可以包括也可以不包括。
- const color = /colou?r/;
- color.test('color'); // returns true
- color.test('colour'); // returns true
你可能還需要關(guān)注的特殊字符是". "字符。這是個(gè)通配符。一個(gè)". "可以代表任何其他字符,不包括換行。
- const anything = /./;
- anything.test('a'); // returns true
- anything.test('1'); // returns true
- anything.test('['); // returns true
嗯,先提這么幾個(gè)基礎(chǔ)的,我們?cè)賮?lái)看看其他的語(yǔ)法。
其他語(yǔ)法
\w "字符指的是任何字母數(shù)字字符。它的反義詞,"\W",指任何非字母數(shù)字字符。
- const alphaNumber = /\w/;
- alphaNumber.test('a'); // returns true
- alphaNumber.test('1'); // returns true
- alphaNumber.test('&'); // returns false
- const notAlphaNumber = /\W/;
- notAlphaNumber.test('a'); // returns false
- notAlphaNumber.test('1'); // returns false
- notAlphaNumber.test('&'); // returns true
再介紹一個(gè),"\s "字符指的是任何空白字符,而"\S "字符指的是任何非空白字符。
- const whitespace = /\s/;
- whitespace.test('a'); // returns false
- whitespace.test('1'); // returns false
- whitespace.test('&'); // returns false
- whitespace.test(' '); // returns true
- whitespace.test('\n'); // returns true
- const notWhitespace = /\S/;
- notWhitespace.test('a'); // returns true
- notWhitespace.test('1'); // returns true
- notWhitespace.test('&'); // returns true
- notWhitespace.test(' '); // returns false
- notWhitespace.test('\n'); // returns false
嗯,不能全部介紹完滴,還得自己查,那么有沒(méi)有總結(jié)性的圖呢,這個(gè)時(shí)候,當(dāng)然有。
一圖解千愁

手冊(cè)
這是一個(gè)第三方網(wǎng)站,推薦結(jié)合這個(gè),右邊的語(yǔ)法參考,基本上是上面的內(nèi)容。
- https://c.runoob.com/front-end/854
左邊調(diào)試,中間是語(yǔ)法參考,右側(cè)是控制臺(tái),豈不美哉。
解題
匹配的格式是=A12/B12/C12.../K23中間是乘法也行。
想了很久,首先,我們是不是可以拆成三部分呢,一頭一尾和中間部分。
開頭,我們是不是可以這么匹配:
- reg = /^=[A-Z]+\d+/i;
首先的是=開頭,然后是字母,接著是數(shù)字,考慮到可能是一個(gè)或者是多個(gè),得用“+”特殊字符。
然后我們看看預(yù)期:
- reg.test('=b12') // true
- reg.test('=C12') // true
- reg.test('=CC3') // true
- reg.test('=CDdd35') // true
- reg.test('=CDdd 35') // false
嗯,我們?cè)趤?lái)看看,尾巴部分怎么寫:
- // 尾巴部分,應(yīng)該都是 /CC12, /B234,這樣子滴
- reg = /(\/|\*)[A-Z]+\d+$/i
首先,考慮到可能是乘法和除法,于是有這樣子的**(/|*)**,需要注意的是,需要轉(zhuǎn)義一下,然后以$結(jié)尾。
- reg.test('/cc') // false
- reg.test('/cc12') // true
剩下的就是中間的部分了,也就是剩下多個(gè)形如: /B231這樣子的結(jié)構(gòu),于是:
- reg = /((\/|\*)[A-Z]+\d+$)*/i
最后組合一下,就是這樣子的:
- const multiplicationAndDivisionReg = /^=[A-Z]+\d+((\/|\*)[A-Z]+\d*$)*(\/|\*)[A-Z]+\d+$/i;
簡(jiǎn)單入門后,留一個(gè)思考題,之前面試看過(guò)一個(gè)有趣的題目,數(shù)字千分位。
- '100000000.00'
- // 輸出 '100,000,000.00'
趕緊來(lái)實(shí)戰(zhàn)一下吧。
最后
今天的分享,簡(jiǎn)單的介紹了如何入門正則表達(dá)式Regex,趕緊動(dòng)手學(xué)起來(lái)吧。