摘要:介紹這周開(kāi)始學(xué)習(xí)老姚大佬的正則表達(dá)式迷你書(shū),然后習(xí)慣性的看完一遍后,整理一下知識(shí)點(diǎn),便于以后自己重新復(fù)習(xí)。感謝原書(shū)作者老姚,本文無(wú)意抄襲,只是作為自己知識(shí)點(diǎn)的整理,后續(xù)也會(huì)整理到自己的知識(shí)庫(kù)網(wǎng)站中。等價(jià)于,表示出現(xiàn)次。
介紹
這周開(kāi)始學(xué)習(xí)老姚大佬的《JavaScript 正則表達(dá)式迷你書(shū)》 , 然后習(xí)慣性的看完一遍后,整理一下知識(shí)點(diǎn),便于以后自己重新復(fù)習(xí)。
我個(gè)人覺(jué)得:自己整理下來(lái)的資料,對(duì)于知識(shí)重現(xiàn),效果不錯(cuò)。
感謝原書(shū)作者老姚,本文無(wú)意抄襲,只是作為自己知識(shí)點(diǎn)的整理,后續(xù)也會(huì)整理到自己的 JavaScript知識(shí)庫(kù)——《Cute-JavaScript》 網(wǎng)站中。
另外,請(qǐng)讀者們注意,這篇文章是知識(shí)點(diǎn)的整理,方便復(fù)習(xí),所以不會(huì)介紹太詳細(xì),因?yàn)楫吘乖瓡?shū)寫(xiě)得非常棒,剛?cè)腴T(mén)的朋友,我還是建議看下原書(shū)。
然后可以看看這篇文章,來(lái)回顧重要知識(shí)點(diǎn)。
《JavaScript 正則表達(dá)式迷你書(shū)》
《Cute-JavaScript》
目錄一、正則表達(dá)式字符匹配
二、正則表達(dá)式位置匹配
三、正則表達(dá)式括號(hào)的使用
四、正則表達(dá)式回溯法原理
五、正則表達(dá)式的拆分
六、正則表達(dá)式的構(gòu)建
七、正則表達(dá)式編程
文章推薦(補(bǔ)充中)老姚 —— JS正則表達(dá)式完整教程
常見(jiàn)的正則表達(dá)式可視化描述
工具推薦Regulex*%3F%24)
Rubular
一、正則表達(dá)式字符匹配原書(shū)這么一句話(huà),特別棒:正則表達(dá)式是匹配模式,要么匹配字符,要么匹配位置,要記住。
1. 兩種模糊匹配正則表達(dá)式的強(qiáng)大在于它的模糊匹配,這里介紹兩個(gè)方向上的“模糊”:橫向模糊和縱向模糊。
橫向模糊匹配
即一個(gè)正則可匹配的字符串長(zhǎng)度不固定,可以是多種情況。
如 /ab{2,5}c/ 表示匹配: 第一個(gè)字符是 "a" ,然后是 2 - 5 個(gè)字符 "b" ,最后是字符 "c" :
let r = /ab{2,5}c/g; let s = "abc abbc abbbc abbbbbbc"; s.match(r); // ["abbc", "abbbc"]
縱向模糊匹配
即一個(gè)正則可匹配某個(gè)不確定的字符,可以有多種可能。
如 /[abc]/ 表示匹配 "a", "b", "c" 中任意一個(gè)。
let r = /a[123]b/g; let s = "a0b a1b a4b"; s.match(r); // ["a1b"]2. 字符組
范圍表示法
可以指定字符范圍,比如 [1234abcdUVWXYZ] 就可以表示成 [1-4a-dU-Z] ,使用 - 來(lái)進(jìn)行縮寫(xiě)。
如果要匹配 "a", "-", "z" 中任意一個(gè)字符,可以這么寫(xiě): [-az] 或 [a-z] 或 [az-] 。
排除字符組
即需要排除某些字符時(shí)使用,通過(guò)在字符組第一個(gè)使用 ^ 來(lái)表示取反,如 [^abc] 就表示匹配除了 "a", "b", "c" 的任意一個(gè)字符。
常見(jiàn)簡(jiǎn)寫(xiě)形式
字符組 | 具體含義 |
---|---|
d | 表示 [0-9],表示一位數(shù)字。 |
D | 表示 [^0-9],表示除數(shù)字外的任意字符。 |
w | 表示 [0-9a-zA-Z_],表示數(shù)字、大小寫(xiě)字母和下劃線(xiàn)。 |
W | 表示 [^0-9a-zA-Z_],表示非單詞字符。 |
s | 表示 [ v f],表示空白符,包含空格、水平制表符、垂直制表符、換行符、回車(chē)符、換頁(yè)符。 |
S | 表示 [^ v f],表示非空白字符。 |
. | 表示 [^ u2028u2029] 。通配符,表示幾乎任意字符。換行符、回車(chē)符、行分隔符和段分隔符除外。 |
然后表示任意字符,就可以使用 [dD]、[wW]、[sS] 和 [^] 任意一個(gè)。
3. 量詞量詞也稱(chēng)重復(fù),常用簡(jiǎn)寫(xiě)如下:
量詞 | 具體含義 |
---|---|
{m,} | 表示至少出現(xiàn) m 次。 |
{m} | 等價(jià)于 {m, m} ,表示出現(xiàn) m 次。 |
? | 等價(jià)于 {0, 1} ,表示出現(xiàn)或不出現(xiàn)。 |
+ | 等價(jià)于 {1, } ,表示至少出現(xiàn)1次。 |
* | 等價(jià)于 {0, } ,表示出現(xiàn)任意次,也有可能不出現(xiàn)。 |
貪婪匹配和惰性匹配
在正則 /d{2,4}/ ,表示數(shù)字連續(xù)出現(xiàn) 2 - 4 次,可以匹配到 2 位、 3 位、4 位連續(xù)數(shù)字。
但是在 貪婪匹配 如 /d{2,4}/g ,會(huì)盡可能多匹配,如超過(guò) 4 個(gè),就只匹配 4 個(gè),如有 3 個(gè),就匹配 3 位。
而在 惰性匹配 如 /d{2,4}?/g ,會(huì) 盡可能少 匹配,如超過(guò) 2 個(gè),就只匹配 2 個(gè),不會(huì)繼續(xù)匹配下去。
let r1 = /d{2,4}/g; let r2 = /d{2,4}?/g; let s = "123 1234 12345"; s.match(r1); // ["123", "1234", "1234"] s.match(r2); // ["12", "12", "34", "12", "34"]
惰性量詞 | 貪婪量詞 |
---|---|
{m,m}? | {m,m} |
{m,}? | {m,} |
?? | ? |
+? | + |
*? | * |
即提供多個(gè)子匹配模式任選一個(gè),使用 |(管道符)分隔,由于分支結(jié)構(gòu)也是惰性,即匹配上一個(gè)后,就不會(huì)繼續(xù)匹配后續(xù)的。
格式如:(r1|r2|r3),我們就可以使用 /leo|pingan/ 來(lái)匹配 "leo" 和 "pingan"。
let r = /leo|pingan/g; let s = "leo cool,pingan good."; s.match(r);// ["leo", "pingan"] // 多選分支的惰性表現(xiàn) let r1 = /leo|leooo/g; let r2 = /leooo|leo/g; let s = "leooo"; s.match(r1);// ["leo"] s.match(r2);// ["leooo"]5. 案例分析
匹配字符,無(wú)非就是字符組、量詞和分支結(jié)構(gòu)的組合使用。
十六進(jìn)制顏色值匹配
let r = /#[0-9a-fA-F]{6}|#[0-9a-fA-F]{3}/g; let s = "#ffaacc #Ff00DD #fFF #01d #9Gd"; s.match(r); // ["#ffaacc", "#Ff00DD", "#fFF", "#01d"]
時(shí)間和日期匹配
// 時(shí)間 12:23 或 01:09 let r = /^([01][0-9]|[2][0-3]):[0-5][0-9]$/; r.test("23:25"); // true r.test("03:05"); // true // 時(shí)間 12:23 或 1:9 let r = /^(0?[0-9]|1[0-9]|[2][0-3]):(0?[0-9]|[1-5][0-9])$/; r.test("23:25"); // true r.test("03:05"); // true r.test("3:5"); // true // 日期 yyyy-mm-dd let r = /^[0-9]{4}-(0[1-9]|[1][0-2])-(0[1-9]|[12][0-9]|3[01])$/; r.test("2019-09-19"); // true r.test("2019-09-32"); // false
Windows操作系統(tǒng)文件路徑匹配
盤(pán)符使用 [a-zA-Z]: ,這里需要注意 字符需要轉(zhuǎn)義,并且盤(pán)符不區(qū)分大小寫(xiě);
文件名或文件夾名,不能包含特殊字符,使用 [^:*<>|"?
/] 表示合法字符;
并且至少有一個(gè)字符,還有可以出現(xiàn)任意次,就可以使用 ([^:*<>|"?
/]+)* 匹配任意個(gè) 文件夾;
還有路徑最后一部分可以是 文件夾 ,即沒(méi)有 于是表示成 ([^:*<>|"?
/]+)?。
let r = /^[a-zA-Z]:([^:*<>|"? /]+)*([^:*<>|"? /]+)?$/; r.test("C:documentleoa.png"); // true r.test("C:documentleo"); // true r.test("C:document"); // true r.test("C:"); // true
id匹配
如提取 tips1:由于 . 匹配雙引號(hào),且 * 貪婪,就會(huì)持續(xù)匹配到最后一個(gè)雙引號(hào)結(jié)束。 位置匹配,就是要匹配每個(gè)字符兩邊的位置。 在 ES5 中有6個(gè)位置: ^,$,,B,(?=p) 和 (?!p)。 另外把位置理解成空字符是非常有用的: ^ 匹配開(kāi)頭,多行中匹配行開(kāi)頭。 多行匹配模式使用 m 修飾符。 匹配單詞邊界,即 w 和 W 之間的位置,包括 w 和 ^ 之間的位置,和 w 和 $ 之間的位置。 p 為一個(gè)子模式,即 (?=p) 匹配前面是 p 的位置,而 (?!p) 則匹配前面不是 p 的位置。 匹配數(shù)字千位分隔符 數(shù)據(jù)格式化 驗(yàn)證密碼 簡(jiǎn)單理解:括號(hào)提供了分組,便于我們使用它。 通常有兩種引用情況:在JS代碼中引入,和在正則表達(dá)式中引入。 分組和分支結(jié)構(gòu),主要是強(qiáng)調(diào)括號(hào)內(nèi)是一個(gè)整體,即提供子表達(dá)式。 分組如 /(ab)+/g 匹配連續(xù)出現(xiàn)的 ab 。 分支結(jié)構(gòu)如 /(a|b)+/g 匹配出現(xiàn)的 a 或 b 表達(dá)式。 如在日期匹配的時(shí)候,就可以這么改造: 提取數(shù)據(jù) 替換 將 yyyy-mm-dd 轉(zhuǎn)成 mm/dd/yyyy。 使用
表示第 n 個(gè)分組,比如 1 表示第 1 個(gè)分組: 多個(gè)括號(hào)嵌套 按照開(kāi)括號(hào)的順序: 特殊情況 10 表示的是第 10 個(gè)分組,若要匹配 和 0 時(shí),使用 (?:1)0 或 1(?:0)。 當(dāng)引用不存在的分組 如匹配 2 是前面不存在,則匹配 2 本身,即對(duì) 2 的轉(zhuǎn)義,不同瀏覽器可能不同: 分組后面有量詞 當(dāng)分組后面有量詞的話(huà),則捕獲的是最后一次的匹配: 這里只寫(xiě)出核心代碼。 模擬字符串 trim 方法 每個(gè)單詞首字母大寫(xiě) 駝峰化 和 中劃線(xiàn)化 匹配成對(duì)HTML標(biāo)簽 匹配成對(duì)標(biāo)簽 概念理解起來(lái)比較容易。 當(dāng)匹配 abbbc,按順序匹配,到了第 3 個(gè) b 后,直接匹配 c,這樣就沒(méi)有回溯。 當(dāng)匹配 abbc,按順序匹配,到了第 2 個(gè) b 后,由于規(guī)則是 b{1,3} ,則會(huì)繼續(xù)往下匹配,然后發(fā)現(xiàn)下一位是 c,于是回退到前一個(gè)位置,重新匹配,這就是回溯。 另外像 /".*"/ 來(lái)匹配 "abc"de 的話(huà),就會(huì)有三個(gè)回溯情況,為了減少不必要的回溯,我們可以把正則修改為 /"[^"]*"/。 介紹 回溯法,也稱(chēng)試探法,本質(zhì)上是深度優(yōu)先探索算法,基本思路是:匹配過(guò)程中后退到之前某一步重新探索的過(guò)程。 貪婪量詞 多個(gè)貪婪量詞挨著存在,并相互沖突時(shí),會(huì)看匹配順序,深度優(yōu)先搜索: 惰性量詞 有時(shí)候會(huì)因?yàn)榛厮?,?dǎo)致實(shí)際惰性量詞匹配到的不是最少的數(shù)量: 分支結(jié)構(gòu) 分支機(jī)構(gòu),如果一個(gè)分支整體不匹配,會(huì)繼續(xù)嘗試剩下分支,也可以看成一種回溯。 簡(jiǎn)單總結(jié):一個(gè)個(gè)嘗試,直到,要么后退某一步整體匹配成功,要么最后試完發(fā)現(xiàn)整體不匹配。 貪婪量詞:買(mǎi)衣服砍價(jià),價(jià)格高了,便宜點(diǎn),再便宜點(diǎn)。 懶惰量詞:賣(mài)衣服加價(jià),價(jià)格低了,多給點(diǎn),再多給點(diǎn)。 分支結(jié)構(gòu):貨比三家,一家不行換一家,不行再換。 拆分正則代碼塊,是理解正則的關(guān)鍵。 在 JavaScrip 正則表達(dá)式有以下結(jié)構(gòu): 字面量: 匹配一個(gè)具體字符,如 a 匹配字符 a。 字符組: 匹配一個(gè)有多種可能性的字符,如 [0-9] 匹配任意一個(gè)數(shù)字。 量詞: 匹配一個(gè)連續(xù)出現(xiàn)的字符,如 a{1,3} 匹配連續(xù)最多出現(xiàn) 3 次的a字符。 錨: 匹配一個(gè)位置,如 ^ 匹配字符串的開(kāi)頭。 分組: 匹配一個(gè)整體,如 (ab) 匹配 ab 兩個(gè)字符連續(xù)出現(xiàn)。 分支: 匹配一個(gè)或多個(gè)表達(dá)式,如 ab|bc 匹配 ab 或 bc 字符。 另外還有以下操作符: Tips:優(yōu)先級(jí)從上到下,由高到低。 匹配字符串整體 不能寫(xiě)成 /^abc|bcd$/ ,而是要寫(xiě)成 /^(abc|bcd)$/。 量詞連綴問(wèn)題 需要匹配:每個(gè)字符是 a/b/c 中其中一個(gè),并且字符串長(zhǎng)度是 3 的倍數(shù): 不能寫(xiě)成 /^[abc]{3}+$/ ,而是要寫(xiě)成 /([abc]{3})+/。 元字符轉(zhuǎn)義問(wèn)題 元字符就是正則中的特殊字符,當(dāng)匹配元字符就需要轉(zhuǎn)義,如: ^、$、.、*、+、?、|、、/、(、)、[、]、{、}、=、!、:、- 。 身份證號(hào)碼 IPV4地址 需要好好分析: 正則的構(gòu)建需要考慮以下幾點(diǎn)的平衡: 匹配預(yù)期的字符串 不匹配非預(yù)期的字符串 可讀性和可維護(hù)性 效率 我們還需要考慮這么幾個(gè)問(wèn)題: 是否需要使用正則 如能使用其他 API 簡(jiǎn)單快速解決問(wèn)題就不需要使用正則: 是否需要使用復(fù)雜正則 /(?!^[0-9]{6,12}$)(?!^[a-z]{6,12}$)(?!^[A-Z]{6,12}$)^[0-9A-Za-z]{6,12}$/ 將這個(gè)正則拆分成多個(gè)小塊,如下: 即需要匹配到預(yù)期目標(biāo),且不匹配非預(yù)期的目標(biāo)。 匹配固定電話(huà) 如需要匹配下面固定電話(huà)號(hào)碼,可以分別寫(xiě)出對(duì)應(yīng)正則: 然后合并: 然后提取公共部分: 再優(yōu)化: 匹配浮點(diǎn)數(shù) 先確定,符號(hào)部分([+-])、整數(shù)部分(d+)和小數(shù)部分(.d+)。 整理后: 正則表達(dá)式運(yùn)行過(guò)程: 編譯 設(shè)定起始位置 嘗試匹配 若匹配失敗則返回前一步重新匹配 返回匹配成功失敗的結(jié)果 我們常常優(yōu)化對(duì) 3 和 4 步進(jìn)行優(yōu)化: 使用具體字符組替代通配符,消除回溯 如 /"[^"]*"/ 代替 /".*?"/。 使用非捕獲型分組 當(dāng)不需要使用分組引用和反向引用時(shí),此時(shí)可以使用非捕獲分組。 如 /^[-]?(?:d.d+|d+|.d+)$/ 代替 /^[-]?(d.d+|d+|.d+)$/。 獨(dú)立出確定字符 加快判斷是否匹配失敗,進(jìn)而加快移位的速度。 如 /aa*/ 代替 /a+/。 提取分支公共部分 減少匹配過(guò)程中可消除的重復(fù)。 如 /^(?:abc|def)/ 代替 /^abc|^def/。 減少分支的數(shù)量,縮小它們的范圍 如 /rea?d/ 代替 /red|read/。 這里要掌握正則表達(dá)式怎么用,通常會(huì)有這么四個(gè)操作: 驗(yàn)證 切分 提取 替換 驗(yàn)證 匹配本質(zhì)上是查找,我們可以借助相關(guān)API操作: 切分 提取 替換
search 和 match 參數(shù)問(wèn)題 這兩個(gè)方法會(huì)把字符串轉(zhuǎn)換成正則,所以要加轉(zhuǎn)義
match 返回結(jié)果的格式問(wèn)題 match 參數(shù)有 g 會(huì)返回所有匹配的內(nèi)容,沒(méi)有 g 則返回標(biāo)準(zhǔn)匹配格式:
test 整體匹配時(shí)需要使用 ^ 和 $
split 的注意點(diǎn) split 第二個(gè)參數(shù)是 結(jié)果數(shù)組的最大長(zhǎng)度: 使用正則分組,會(huì)包含分隔符: 修飾符 文章到這結(jié)束,感謝閱讀,也感謝老姚大佬的這本書(shū) 文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。 轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/102610.html 摘要:本文內(nèi)容共正則表達(dá)式火拼系列正則表達(dá)式回溯法原理學(xué)習(xí)正則表達(dá)式,是需要懂點(diǎn)兒匹配原理的。正則表達(dá)式迷你書(shū)問(wèn)世了讓幫你生成和解析參數(shù)字符串最全正則表達(dá)式總結(jié)驗(yàn)證號(hào)手機(jī)號(hào)中文郵編身份證地址等是正則表達(dá)式的縮寫(xiě),作用是對(duì)字符串執(zhí)行模式匹配。
JS 的正則表達(dá)式
正則表達(dá)式 一種幾乎可以在所有的程序設(shè)計(jì)語(yǔ)言里和所有的計(jì)算機(jī)平臺(tái)上使用的文字處理工具。它可以用來(lái)查找特定的信息(搜索),也可以用來(lái)查... 摘要:比如正則表示匹配這樣一個(gè)字符串第一個(gè)字符是,接下來(lái)是到個(gè)字符,最后是字符。其實(shí)現(xiàn)的方式是使用字符組。具體形式如下,其中和是子模式,用管道符分隔,表示其中任何之一。
貪婪模式:
在使用修飾匹配次數(shù)的特殊符號(hào)時(shí),有幾種表示方法可以使同一個(gè)表達(dá)式能夠匹配不同的次數(shù),比如:{m,n}, {m,}, ?, *, +,具體匹配的次數(shù)隨被匹配的字符串而定。這種重復(fù)匹配不定次數(shù)的表達(dá)式在匹配過(guò)程中,總... 摘要:使用看完你就會(huì)正則表達(dá)式了四種操作驗(yàn)證切分提取替換第一章正則表達(dá)式字符匹配攻略正則表達(dá)式是匹配模式,要么匹配字符,要么匹配位置至少,至多匹配中的任一個(gè)字符范圍表示法如果要匹配則要么要么要么通配符,表示幾乎任意
API 使用
String#search
String#split
String#match
String#replace
RegExp#test
Reg... 摘要:提供了完整的環(huán)境,并且支持自定義域名指向,動(dòng)態(tài)計(jì)算資源調(diào)整,可以完成各種應(yīng)用的開(kāi)發(fā)編譯與部署。
react 新特性
react16 Context
算法相關(guān)
圖解排序算法(二)之希爾排序
微信小程序
微信小程序組件化的解決方案移動(dòng)端尺寸基本知識(shí)
瀏覽器
前端必讀:瀏覽器內(nèi)部工作原理瀏覽器緩存原理解讀瀏覽器加載css和js及dom解析之間的關(guān)系瀏覽器緩存
CSS學(xué)習(xí)
移動(dòng)web開(kāi)發(fā)布局入... showImg(https://segmentfault.com/img/bVbfGSV?w=719&h=718);
showImg(https://segmentfault.com/img/bVbfGTc?w=801&h=552);
showImg(https://segmentfault.com/img/bVbfGTq?w=1017&h=501);let r1 = /id=".*"/; // tips1
let r2 = /id=".*?"/; // tips2
let r3 = /id="[^"]*"/; // tips3
let s = "
tips2:使用惰性匹配,但效率低,有回溯問(wèn)題。
tips3:最終優(yōu)化。/^^hello$$/.test("hello"); // true
/^^^hello$$/.test("hello"); // true
1. ^ 和 $
$ 匹配結(jié)尾,多行中匹配行結(jié)尾。"hello".replace(/^|$/g, "#"); // "#hello#"
"hello
leo
haha".replace(/^|$/gm, "#");
/*
#hello#
#leo#
#haha#
*/
B 和 相反,即非單詞邊界,匹配中除去 ,剩下的都是 B 的。
也就是 w 與 w、 W 與 W、^ 與 W,W 與 $ 之間的位置。。"[HI] Leo_1.mp4".replace(//g,"#");
// "[#HI#] #Leo_1#.#mp4#"
"[HI] Leo_1.mp4".replace(/B/g,"#");
// "#[H#I]# L#e#o#_#1.m#p#4"
3. (?=p) 和 (?!p)
"hello".replace(/(?=l)/g, "#");
// "he#l#lo"
"hello".replace(/(?!l)/g, "#");
// "#h#ell#o#"
4. 相關(guān)案例
// 匹配最后一個(gè)逗號(hào)
"12345678".replace(/(?=d{3}$)/g, ","); // "12345,678"
// 匹配所有逗號(hào)
"12345678".replace(/(?=(d{3})+$)/g, ","); // "12,345,678"
// 匹配其余
"123456789".replace(/(?=(d{3})+$)/g, ","); // ",123,456,789"
// 修改
"123456789".replace(/(?!^)(?=(d{3})+$)/g, ","); // "12,345,678"
// 其他形式
"12345678 123456789".replace(/(?!)(?=(d{3})+)/g, ",");
// (?!) 等于 B ,要求當(dāng)前是一個(gè)位置,但不是 前面的位置
// "12,345,678 123,456,789"
let num = 1888;
num.toFixed(2).replace(/B(?=(d{3})+)/g, ",").replace(/^/,"$$ ");
// "$ 1,888.00"
// 密碼長(zhǎng)度 6-12 位數(shù)字或字母
let r = /^[0-9A-Za-z]{6,12}$/;
// 必須包含一個(gè)字符(數(shù)字) + 密碼長(zhǎng)度 6-12 位數(shù)字或字母
let r = /(?=.*[0-9])^[0-9A-Za-z]{6,12}$/;
// 必須包含兩個(gè)個(gè)字符(數(shù)字和小寫(xiě)字符) + 密碼長(zhǎng)度 6-12 位數(shù)字或字母
let r = /(?=.*[0-9])(?=.*[a-z])^[0-9A-Za-z]{6,12}$/;
r.test("aa1234566"); // true
r.test("1234566"); // false
// 密碼長(zhǎng)度 6-12 位數(shù)字或字母
// 即 不能全是數(shù)字 或 不能全是大寫(xiě)或小寫(xiě)字母
let r = /(?!^[0-9]{6,12}$)(?!^[a-z]{6,12}$)(?!^[A-Z]{6,12}$)^[0-9A-Za-z]{6,12}$/;
三、正則表達(dá)式括號(hào)的使用
// 原來(lái)
let r = /d{4}-d{2}-d{2}/;
// 現(xiàn)在
let r = /(d{4})-(d{2})-(d{2})/;
"2019-03-14".match(r);
r.exec("2019-03-14");
// ["2019-03-14", "2019", "03", "14", index: 0, input: "2019-03-14"]
RegExp.$1; // "2019"
RegExp.$2; // "03"
RegExp.$3; // "14"
"2019-03-14".replace(r, "$2/$3/$1");
// 等價(jià)于
"2019-03-14".replace(r, function(){
return RegExp.$2 + "/" + RegExp.$3 + "/" + RegExp.$1;
});
2. 反向引用
let r = /d{4}(-|/|.)d{2}1d{2}/;
r.test("2019-03-15");
r.test("2019/03/15");
r.test("2019.03.15");
r.test("2019-03/15");
let r = /^((d)(d(d)))1234$/;
let s = "1231231233";
r.test(s);
console.log([RegExp.$1,RegExp.$2,RegExp.$3,RegExp.$4]);
// ["123", "1", "23", "3"]
let r = /(1)(2)(3)(4)(5)(6)(7)(8)(9)(#) 10+/;
let s = "123456789# #####";
r.test(s); // true
let r = /1234/;
r.test("1234"); // true
"1234".split("");// ["", "", "", ""]
"12345".match(/(d)+/); // ["12345", "5", index: 0, input: "12345"]
/(d)+ 1/.test("12345 1"); // false
/(d)+ 1/.test("12345 5"); // true
3. 相關(guān)案例
// 1 匹配首尾空白符,替換成空字符
" aaa ".replace(/^s+|s+$/g, ""); // "aaa"
// 2 匹配整個(gè)字符串,再用引用提取對(duì)應(yīng)數(shù)據(jù)
" aaa ".replace(/^s*(.*?)s*$/g, "$1");// "aaa"
"hi leo hi boy!".toLowerCase().replace(
/(?:^|s)w/g,
c => c.toUpperCase()
);
// "Hi Leo Hi Boy!"
"-leo-and-pingan".replace(/[-_s]+(.)?/g,
(match, c) => c ? c.toUpperCase() : ""
);
// "LeoAndPingan"
"LeoAndPingan".replace(/([A-Z])/g, "-$1").replace(
/[-_s]+g/,"-"
).toLowerCase();
// "-leo-and-pingan"
leo
,而不匹配不成對(duì)標(biāo)簽 leo
。let r = /<([^>]+)>[dD]*1>/;
r.test("
四、正則表達(dá)式回溯法原理
leo leo leo
"); // true
r.test("leo leo leo"); // true
r.test("leo leo leo"); // false
比如用 /ab{1,3}c/ 去匹配下面兩個(gè)字符串。"12345".match(/(d{1,3})(d{1,3})/);
// ?["12345", "123", "45", index: 0, input: "12345"]
"12345".match(/(d{1,3}?)(d{1,3})/);
// 沒(méi)有回溯的情況?["1234", "1", "234", index: 0, input: "12345"]
"12345".match(/^d{1,3}?d{1,3}$/);
// 有回溯的情況?["12345", index: 0, input: "12345"]
"candy".match(/can|candy/); // ["can", index: 0, input: "candy"]
"candy".match(/^(?:can|candy)$/); // ["candy", index: 0, input: "candy"]
2. 本章小結(jié)
優(yōu)先級(jí)
操作符描述
操作符
1
轉(zhuǎn)義符
2
括號(hào)和方括號(hào)
(...)/(?:...)/(?=...)/(?!...)/[...]
3
量詞限定符
{m}/{m,n}/{m,}/?/*/+
4
位置和序列
^/$/元字符/一般字符
5
管道符
`
`
// "[abc]" => /[abc]/ 或者 /[abc]/
// "{1,3}" => /{1}/ 或者 /{1}/ 因?yàn)椴粯?gòu)成字符組
2. 案例分析
/^(d{15}|d{17})[dxX]$/.test("390999199999999999");// true
let r = /^((0{0,2}d|0?d{2}|1d{2}|2[0-4]d|25[0-5]).){3}(0{0,2}d|0?d{2}|1d{2}|2[0-4]d|25[0-5])$/
六、正則表達(dá)式的構(gòu)建
"2019-03-16".match(/^(d{4})-(d{2})-(d{2})/); // 間接獲取?["2019", "03", "16"]
"2019-03-16".split("-"); // ?["2019", "03", "16"]
"?id=leo".search(/?/); // 0
"?id=leo".indexOf("?"); // 0
"JavaScript".match(/.{4}(.+)/)[1]; // "Script"
"JavaScript".substring(4); // "Script"
var regex1 = /^[0-9A-Za-z]{6,12}$/;
var regex2 = /^[0-9]{6,12}$/;
var regex3 = /^[A-Z]{6,12}$/;
var regex4 = /^[a-z]{6,12}$/;
function checkPassword (string) {
if (!regex1.test(string)) return false;
if (regex2.test(string)) return false;
if (regex3.test(string)) return false;
if (regex4.test(string)) return false;
return true;
}
1. 準(zhǔn)確性
055188888888 => /^0d{2,3}[1-9]d{6,7}$/
0551-88888888 => /^0d{2,3}-[1-9]d{6,7}$/
(0551)88888888 => /^0d{2,3}-[1-9]d{6,7}$/
let r = /^0d{2,3}[1-9]d{6,7}$|^0d{2,3}-[1-9]d{6,7}$|^(0d{2,3})[1-9]d{6,7}$/
let r = /^(0d{2,3}|0d{2,3}-|(0d{2,3}))[1-9]d{6,7}$/
let r = /^(0d{2,3}-?|(0d{2,3}))[1-9]d{6,7}$/
1.23、+1.23、-1.23 => /^[+-]?d+.d+$/
10、+10、-10 => /^[+-]?d+$/
.2、+.2、-.2 => /^[+-]?.d+$/
let r = /^[+-]?(d+.d+|d+|.d+)$/;
// 考慮不匹配 +.2 或 -.2
let r = /^([+-])?(d+.d+|d+|.d+)$/;
// 考慮不匹配 012 這類(lèi) 0 開(kāi)頭的整數(shù)
let r = /^[+-]?(d+)?(.)?d+$/;
2. 效率
// 檢查字符串是否包含數(shù)字
let r = /d/, s = "abc123";
!!s.search(r); // true
r.test(s); // true
!!s.match(r); // true
!!r.exec(s); // true
"leo,pingan".split(/,/); // ["leo", "pingan"]
let r = /D/, s = "2019-03-16";
s.split(r); //?["2019", "03", "16"]
s.split(r); //?["2019", "03", "16"]
s.split(r); //?["2019", "03", "16"]
// 提取日期年月日
let r = /^(d{4})D(d{2})D(d{2})$/;
let s = "2019-03-16";
s.match(r); // ["2019-03-16", "2019", "03", "16", index: 0, input: "2019-03-16"]
r.exec(s); // ["2019-03-16", "2019", "03", "16", index: 0, input: "2019-03-16"]
r.test(s); // RegExp.$1 => "2019" RegExp.$2 => "03" RegExp.$3 => "16"
s.search(r);// RegExp.$1 => "2019" RegExp.$2 => "03" RegExp.$3 => "16"
// yyyy-mm-dd 替換成 yyyy/mm/dd
"2019-03-16".replace(/-/g, "/");
2. 相關(guān)API注意
let s = "2019.03.16";
s.search("."); // 0
s.search("."); // 4
s.search(/./); // 4
s.match("."); // ["2", index: 0, input: "2019.03.16"]
s.match("."); // [".", index: 4, input: "2019.03.16"]
s.match(/./); // [".", index: 4, input: "2019.03.16"]
// 其他不用轉(zhuǎn)義
s.split(".");
s.replace(".", "/");
let s = "2019.03.16";
s.match(/(d+)/); // ["2019", "2019", index: 0, input: "2019.03.16"]
s.match(/(d+)/g); // ["2019", "03", "16"]
/123/.test("a123b"); // true
/^123$/.test("a123b"); // false
/^123$/.test("123"); // true
"leo,pingan,pingan8787".split(/,/, 2); // ["leo", "pingan"]
"leo,pingan,pingan8787".split(/(,)/); // ["leo", ",", "pingan", ",", "pingan8787"]
修飾符
描述
g
全局匹配,即找到所有匹配的,單詞是 global。
i
忽略字母大小寫(xiě),單詞是 ingoreCase。
m
多行匹配,只影響 ^ 和 $,二者變成行的概念,即行開(kāi)頭和行結(jié)尾。單詞是 multiline。
微信公眾號(hào)
Author
王平安
E-mail
pingan8787@qq.com
博 客
www.pingan8787.com
微 信
pingan8787
每日文章推薦
https://github.com/pingan8787...
ES小冊(cè)
js.pingan8787.com
相關(guān)文章
正則表達(dá)式
JavaScript正則表達(dá)式迷你書(shū)-筆記
正則表達(dá)式迷你書(shū)-筆記
前端學(xué)習(xí)資源
javascript正則迷你書(shū)-筆記
發(fā)表評(píng)論
0條評(píng)論
閱讀 1467·2023-04-26 00:08
閱讀 797·2021-11-23 18:51
閱讀 1672·2021-11-12 10:34
閱讀 1008·2021-10-14 09:43
閱讀 502·2021-08-18 10:23
閱讀 2581·2019-08-30 15:55
閱讀 3392·2019-08-30 11:05
閱讀 2792·2019-08-29 12:50