久久综合九色综合97婷婷-美女视频黄频a免费-精品日本一区二区三区在线观看-日韩中文无码有码免费视频-亚洲中文字幕无码专区-扒开双腿疯狂进出爽爽爽动态照片-国产乱理伦片在线观看夜-高清极品美女毛茸茸-欧美寡妇性猛交XXX-国产亚洲精品99在线播放-日韩美女毛片又爽又大毛片,99久久久无码国产精品9,国产成a人片在线观看视频下载,欧美疯狂xxxx吞精视频

有趣生活

當(dāng)前位置:首頁>知識(shí)>正則表達(dá)式的一些基本用法(直接告訴你這些常用正則表達(dá)式是怎么寫出來的)

正則表達(dá)式的一些基本用法(直接告訴你這些常用正則表達(dá)式是怎么寫出來的)

發(fā)布時(shí)間:2024-01-23閱讀(14)

導(dǎo)讀作為一名程序員,不會(huì)寫正則表達(dá)式總感覺少了點(diǎn)什么,不要求你能把正則玩出花來,但最起碼要對(duì)常用的正則表達(dá)式手到擒來,剛畢業(yè)的我對(duì)于正則也是一頭霧水,不過學(xué)會(huì)它....

作為一名程序員,不會(huì)寫正則表達(dá)式總感覺少了點(diǎn)什么,不要求你能把正則玩出花來,但最起碼要對(duì)常用的正則表達(dá)式手到擒來,剛畢業(yè)的我對(duì)于正則也是一頭霧水,不過學(xué)會(huì)它也就一篇教程的事情[1],下面我們就來說一說關(guān)于正則表達(dá)式的一些基本用法?我們一起去了解并探討一下這個(gè)問題吧!

正則表達(dá)式的一些基本用法(直接告訴你這些常用正則表達(dá)式是怎么寫出來的)

正則表達(dá)式的一些基本用法

作為一名程序員,不會(huì)寫正則表達(dá)式總感覺少了點(diǎn)什么,不要求你能把正則玩出花來,但最起碼要對(duì)常用的正則表達(dá)式手到擒來,剛畢業(yè)的我對(duì)于正則也是一頭霧水,不過學(xué)會(huì)它也就一篇教程的事情[1]

本文我不會(huì)再浪費(fèi)帶寬把正則的規(guī)則再次重復(fù)一遍,而是從實(shí)際入手,直接告訴你為什么這么寫

16進(jìn)制顏色

按照規(guī)則來

  1. 以 # 開頭
  2. 后面緊跟著6個(gè)字符或者3個(gè)字符作為結(jié)尾,這些字符可以是 a-f 的小寫字母、A-F的大寫字母、數(shù)字

第一句,可以寫成 /^#/;第二句,[a-fA-F0-9] 表示任意的 a-f、A-F、0-9,6或 3的個(gè)數(shù)可以用 {6}、{3}進(jìn)行表示,那么3個(gè)字符就是 [a-fA-F0-9]{3},6個(gè)字符就是 [a-fA-F0-9]{6},這兩個(gè)都有可能,用一個(gè)或(|)符號(hào)來連接:([a-fA-F0-9]{6}|[a-fA-F0-9]{3}),最后結(jié)尾可以用個(gè) $

所有合到一起就是 /^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/

鏈接

目標(biāo)是匹配出協(xié)議、域名、端口號(hào)port、path、search

  1. 協(xié)議

合法的協(xié)議有 http、https,還有一個(gè)是自適應(yīng)協(xié)議,即不明確加協(xié)議,跟當(dāng)前頁面的協(xié)議保持一致,所以以下都是合法的:http://toutiao.com、https://toutiao.com、//toutiao.com。這三個(gè)協(xié)議組成的鏈接共同點(diǎn)是肯定有 // 字符串,在 //的前面可能是 https: 也可能是 http: 也可以沒有任何字符串 先按照 https:// 這種寫規(guī)則:^https://,其中的 s 字符可能有也可能沒有,所以使用 ? 修飾:^https?://,又因?yàn)?https?:可能沒有,所以這個(gè)字符串也用 ?修飾:^(https?:)?//

  1. 域名

域名的前面可能是 //,從 //往后面匹配,只要沒有代表 :的 port、代表 search 的 ?、代表 path的 /,那么就都屬于域名:[^?:/]

  1. 端口號(hào) port

端口號(hào)肯定以 : 開頭,后面跟著的只要是數(shù)字就都屬于 port::d ,由于不一定有端口號(hào),所以用 ? 修飾:(:d )?

  1. path

肯定以 / 開頭,只要不遇到代表 search 的 ?,那么就都屬于 path:/[^?]*,由于可能沒有 path,所以用 ? 修飾:(/[^?]*)? 5. search 肯定以 ? 開頭,后面所有的字符都屬于 search(不考慮 hash 路由):?(.*),由于可能沒有 search,所以用 ? 修飾:(?.*)?

最后把上面所有規(guī)則合起來就是提取鏈接的完整正則了,考慮到需要精確提取所需要的部分,所以會(huì)對(duì)所需要提取的部分加上小括號(hào),結(jié)果為:/^((https?):)?//([^?:/] )(:(d ))?(/[^?]*)?(?(.*))?/

郵箱

以前在知乎上看到過一段郵箱正則,號(hào)稱是最符合標(biāo)準(zhǔn)的正則表達(dá)式,那條正則的體積好像有幾十KB吧,總之很長,現(xiàn)在找不到了,這里只關(guān)注常用的郵箱格式,規(guī)則:名稱允許漢字、字母、數(shù)字,下劃線,中劃線,域名可以有數(shù)字、字母、下劃線、中劃線組成

漢字的范圍是 [u4e00-u9fa5],字母的范圍是 [a-zA-Z],數(shù)字的范圍是 [0-9],合起來組成郵箱的名稱 ^[A-Za-z0-9-_u4e00-u9fa5]

域名是 [a-zA-Z0-9_-] ,域名后綴可以是多級(jí)域名 (.[a-zA-Z0-9_-] )

上面組合起來就是 ^[A-Za-z0-9-_u4e00-u9fa5] @[a-zA-Z0-9_-] (.[a-zA-Z0-9_-] ) $

手機(jī)號(hào)

手機(jī)號(hào)的號(hào)段可能是會(huì)增加的,所以在實(shí)際場(chǎng)景中不建議限制得太死了

本正則按照以下規(guī)則編寫:

  1. 11位數(shù)字,以數(shù)字 1 開頭,即 ^1
  2. 接下來的數(shù)字如果是 3,那么 3后面可以跟一個(gè)任意數(shù)字,即 3d;如果是 4,那么 4后面可以跟一個(gè)5-9之間的數(shù)字,即 4[5-9];如果是 5,那么 5后面可以跟一個(gè)0-3或5-9之間的數(shù)字,即 5[0-35-9];如果是 6,那么 6后面可以跟 2、5、6、7 其中一個(gè)數(shù)字,即 6[2567];如果是 7,那么 7后面可以跟一個(gè)0-8之間的數(shù)字,即 7[0-8];如果是 8,那么 8后面可以跟一個(gè)任意數(shù)字,即 8d;如果是 9,那么 9后面可以跟一個(gè)0-3或5-9之間的數(shù)字,即 9[0-35-9]
  3. 最后 8位可以是任意數(shù)字

上述三步合起來就是 /^1(3d|4[5-9]|5[0-35-9]|6[2567]|7[0-8]|8d|9[0-35-9])d{8}$/

數(shù)字/貨幣金額

  1. 支持負(fù)數(shù)

負(fù)號(hào)用 -負(fù)號(hào),且必須在第一位,即 ^-,再加個(gè) ? 用于表示這個(gè)負(fù)號(hào)可以有也可以沒有,即 ^-? 2. 支持千分位分隔(沒有也沒關(guān)系) 如果有千分位,則千分位的后面必然跟著三位數(shù)字(否則這個(gè)千分號(hào)就不應(yīng)該加了),千分位前面最少一位、最多三位數(shù)字,那么可以寫成 d{1,3},d{3},再精簡下,千分位前面的數(shù)字其實(shí)可以不用限制,因?yàn)橹灰^三位肯定就有千分位,就會(huì)被 d{3}捕獲,所以 d{1,3}換成 d 就行了,因?yàn)榉锨Х治坏目梢杂卸鄠€(gè)也可能沒有,所以寫成 d (,d{3})* 3. 如果有小數(shù),則小數(shù)點(diǎn)后最多兩位 小數(shù)點(diǎn)就是 .,后面跟著最多兩位數(shù)字 d{1,2},可能有小數(shù)也可能沒有,所以整體需要再加個(gè) ? 符號(hào),即 (.d{1,2})?

最終規(guī)則 /^-?d (,d{3})*(.d{1,2})?$/

身份證號(hào)

這里只看 2代身份證,18位數(shù)字 最后一位是校驗(yàn)位,可能為數(shù)字或字符X

  1. 第一位數(shù)字在 [1-9] 閉區(qū)間內(nèi),后面緊跟著5位任意數(shù)字,寫成 ^[1-9]d{5}
  2. 再緊跟著的四位數(shù)字代表年份(YYYY),因?yàn)槟壳坝猩矸葑C的人最早是19世紀(jì)最晚21世紀(jì),所以這四個(gè)數(shù)字中的前兩位只看是 18、19、20,即 (18|19|20),后兩位則可以是任意數(shù)字,即 d{2}
  3. 再緊跟著兩位數(shù)字是月(MM),月份只可能是 [1-12]閉區(qū)間,所以可以寫成 (01|02|03|04|05|06|07|08|09|10|11|12),前九位的開頭都是 0,第二位是 [1-9] 內(nèi)的數(shù)字,所以簡化成 (0[1-9]|10|11|12)
  4. 再緊跟著兩位數(shù)字是日(DD),范圍是 [01-31],可以將這31個(gè)數(shù)字羅列出來,當(dāng)然也可以精簡下,看成是 [00-09]、[10-29]、[30-31]的組合,即 (0[1-9]|[1-2]d|30|31)
  5. 再緊跟著三位數(shù)字是順序碼,即 d{3}
  6. 最后一位是校驗(yàn)碼,可以是數(shù)字也可以是 X,即 [dX]

最終規(guī)則 /^[1-9]d{5}(18|19|20)d{2}(0[1-9]|10|11|12)(0[1-9]|[1-2]d|30|31)d{3}[dX]$/

密碼校驗(yàn)

最少6位,包括至少1個(gè)大寫字母,1個(gè)小寫字母,1個(gè)數(shù)字,1個(gè)特殊字符

對(duì)于 至少1個(gè)大寫字母 這條規(guī)則,這個(gè)大寫字母的位置是不固定的,只要有就行,如果只有這一條規(guī)則的話,正則可以寫成 ^S*[A-Z] S*$,S 匹配任意非空白字符,這個(gè)規(guī)則即代表大寫字母的前面、后面可以跟著任意個(gè)(包括0個(gè))非空白字符

但除此之外還需要滿足最少1個(gè)小寫字母,1個(gè)數(shù)字,1個(gè)特殊字符,最少6位,你可以將這幾條規(guī)則都單獨(dú)寫出正則,然后目標(biāo)字符串跟這5條正則一一匹配,只要全部能匹配上就是對(duì)的,寫成 js 代碼就是:

functionmatch(s:string){return/^S*[A-Z] S*$/.test(s)&&/^S*[a-z] S*$/.test(s)&&/^S*[0-9] S*$/.test(s)&&/^S*[!@#$%^&*?] S*$/.test(s)&&/^S*S{6,}S*$/.test(s)}復(fù)制代碼

如果就想在一條正則里實(shí)現(xiàn)這些校驗(yàn)?zāi)兀彩强梢缘模枰柚?零寬度正預(yù)測(cè)先行斷言 ((?=exp)),代表 匹配exp前面的位置

有了這個(gè)東西,就可以把上面5條規(guī)則寫到一起去了:/^S*(?=S{6,})(?=S*d)(?=S*[A-Z])(?=S*[a-z])(?=S*[!@#$%^&*?])S*$/

這條正則前面后面的 S* 還是之前的意思不變,中間是提取了5條規(guī)則的個(gè)性部分,然后通過 ?= 放在一起了,把規(guī)則里所有的 ?=去掉行不行?不行,因?yàn)槿绻サ舻脑挘紫染陀许樞蛏系臎_突了,例如上面的規(guī)則,如果把所有的 ?=去掉,就代表著 數(shù)字必須在大寫字母前面,大寫字母必須在小寫字母前面,特殊字母必須在小寫字母前面(除此之外整個(gè)正則也是有問題的)

你可以認(rèn)為 ?= 在匹配的時(shí)候會(huì)忽略掉其他的 ?=,只關(guān)心自己的前面能不能匹配成功,有多個(gè) ?=,則這多個(gè) ?= 都是只關(guān)心自己,忽略其他,但整條正則最后的結(jié)果是所有 ?= 匹配結(jié)果的并集,計(jì)算邏輯和上面的 js 是差不多的

提取 HTML 標(biāo)簽數(shù)據(jù)

要提取的標(biāo)簽字符串類似于 <div name="header">

只是正則話無法完成,需要借助 js

首先,把標(biāo)簽的屬性提取出來

這段標(biāo)簽包含標(biāo)簽開始符號(hào)、tag、屬性字符串、標(biāo)簽結(jié)束符號(hào)

開始符號(hào)是 <,標(biāo)簽名緊跟著開始符號(hào),且只要沒遇到空白符就都是標(biāo)簽名,所以連起來就是 <w s*

在開始符號(hào) 標(biāo)簽名,和 結(jié)束符號(hào)的中間,都是屬性,結(jié)束符號(hào)是 >,所以只要沒遇到結(jié)束符號(hào) >,就認(rèn)為是屬性字符串,用到了反向選擇 [^>]*s*>,合起來就是 /<w s*[^>]*s*>/,為了能捕獲屬性字符串,加個(gè)小括號(hào),即 /<w s*([^>]*)s*>/

conststr=`<divname="header">`constmt=str.match(/<w s*([^>]*)s*>/)//properties即屬性字符串,即name="header"constproperties=mt[1]復(fù)制代碼

取到了 name="header" 之后,再對(duì)其進(jìn)行處理,觀察規(guī)律,每個(gè)屬性的鍵值對(duì)之間肯定存在空白符,不過卻不能通過空白符來直接分割,因?yàn)閷傩灾凳强梢源嬖诳瞻追模?

由于可能是自閉合標(biāo)簽,自閉合標(biāo)簽的最后有沒有 / 都是合法的,例如 <hr> 和 hr />都是合法的,所以需要兼容下:/<w s*([^>]*)s*/?>/

但屬性名是可以確定的,它可能是 = 左邊不包括空白符的內(nèi)容,再次用到反向選擇,從左往右匹配,反向選擇既不是=也不是不是空白符的內(nèi)容,即 [^s=]

雖然不確定屬性值是否包含空白符,但有個(gè)是確定的,即屬性值必然被引號(hào)包圍,所以直接取 = 右側(cè)所有引號(hào)的內(nèi)容即可,=".*?"

不過還有個(gè)問題,引號(hào)不僅可以是單引號(hào)還可以是雙引號(hào),即 =".*?" 和 =.*? 都行,如果第一個(gè)引號(hào)是雙引號(hào)開頭那么對(duì)應(yīng)的第二個(gè)引號(hào)也必然是雙引號(hào),反義單引號(hào)亦然,這里需要用到捕獲的規(guī)則了 =(["]).*?1,1的意思是這塊匹配的內(nèi)容跟第一捕獲組一樣,第一捕獲組也就是 ["],如果第一捕獲組匹配的是雙引號(hào),那么 1 就代表雙引號(hào),否則就代表單引號(hào)

至此整個(gè)正則為 [^s=] =(["]).*?1

不過還有個(gè)問題,屬性是可以沒有屬性值的,例如 <input type="checkbox" checked />,這里 checked 就是可以不寫屬性值的,所以再兼容下:/[^s=] (=(["]).*?2)?/,又因?yàn)橄M蹲綄傩院蛯傩灾担越o屬性和屬性值加個(gè)小括號(hào):/([^s=] )(=(["])(.*?)3)?/

上面的代表就可以繼續(xù)寫了

conststr=`<divname="header">`constmt=str.match(/<w s*([^>]*)s*>/)//properties即屬性字符串,即name="header"constproperties=mt[1]constmt1=properties.match(/([^s=] )(=(["])(.*?)3)?/g)constobj={}if(mt1){mt1.forEach(p=>{constkv=p.trim().split(=)obj[kv[0].trim()]=kv[1].trim().slice(1,-1)})}//obj=>{class:header-box,name:header}復(fù)制代碼

小結(jié)

學(xué)會(huì)正則的最接途徑就是勤加練習(xí),平時(shí)遇到可以用正則解決的問題,就嘗試著正則解決,或許你一開始寫不出來,但可以去網(wǎng)上看看別人是怎么寫的,再自己獨(dú)立寫一遍,寫得多了自然就會(huì)了,沒什么訣竅,無非就是對(duì)正則規(guī)則的熟練掌握罷了

關(guān)于本文

來自:清夜

https://juejin.cn/post/7073360739410378760

歡迎分享轉(zhuǎn)載→http://m.avcorse.com/read-104488.html

Copyright ? 2024 有趣生活 All Rights Reserve吉ICP備19000289號(hào)-5 TXT地圖HTML地圖XML地圖