摘要:雖然正則中可以匹配任何字符,但卻無(wú)法匹配換行符。精讀文中列舉的四個(gè)新特性是加入到正則中的。討論地址是精讀正則如果你想?yún)⑴c討論,請(qǐng)點(diǎn)擊這里,每周都有新的主題,周末或周一發(fā)布。
1. 引言
本周精讀的文章是 regexp-features-regular-expressions。
這篇文章介紹了 ES2018 正則支持的幾個(gè)重要特性:
Lookbehind assertions - 后行斷言
Named capture groups - 命名捕獲組
s (dotAll) Flag - . 匹配任意字符
Unicode property escapes - Unicode 屬性轉(zhuǎn)義
2. 概述還在用下標(biāo)匹配內(nèi)容嗎?匹配任意字符只有 [wW] 嗎?現(xiàn)在正則有更簡(jiǎn)化的寫法了,事實(shí)上正則正在變得更加易用,是時(shí)候更新對(duì)正則的認(rèn)知了。
2.1. Lookbehind assertions完整的斷言定義分為:正/負(fù)向斷言 與 先/后行斷言 的笛卡爾積組合,在 ES2018 之前僅支持先行斷言,現(xiàn)在終于支持了后行斷言。
解釋一下這四種斷言:
正向先行斷言 (?=...) 表示之后的字符串能匹配 pattern。
const re = /Item(?= 10)/; console.log(re.exec("Item")); // → null console.log(re.exec("Item5")); // → null console.log(re.exec("Item 5")); // → null console.log(re.exec("Item 10")); // → ["Item", index: 0, input: "Item 10", groups: undefined]
負(fù)向先行斷言 (?!...) 表示之后的字符串不能匹配 pattern。
const re = /Red(?!head)/; console.log(re.exec("Redhead")); // → null console.log(re.exec("Redberry")); // → ["Red", index: 0, input: "Redberry", groups: undefined] console.log(re.exec("Redjay")); // → ["Red", index: 0, input: "Redjay", groups: undefined] console.log(re.exec("Red")); // → ["Red", index: 0, input: "Red", groups: undefined]
在 ES2018 后,又支持了兩種新的斷言方式:
正向后行斷言 (?<=...) 表示之前的字符串能匹配 pattern。
先行時(shí)字符串放前面,pattern 放后面;后行時(shí)字符串放后端,pattern 放前面。先行匹配以什么結(jié)尾,后行匹配以什么開(kāi)頭。
const re = /(?<=€)d+(.d*)?/; console.log(re.exec("199")); // → null console.log(re.exec("$199")); // → null console.log(re.exec("€199")); // → ["199", undefined, index: 1, input: "€199", groups: undefined]
負(fù)向后行斷言 (? 表示之前的字符串不能匹配 pattern。
注:下面的例子表示 meters 之前 不能匹配 三個(gè)數(shù)字。
const re = /(?文中給了一個(gè)稍復(fù)雜的例子,結(jié)合了 正向后行斷言 與 負(fù)向后行斷言:
注:下面的例子表示 meters 之前 能匹配 兩個(gè)數(shù)字,且 之前 不能匹配 數(shù)字 35.const re = /(?<=d{2})(? 2.2. Named Capture Groups命名捕獲組可以給正則捕獲的內(nèi)容命名,比起下標(biāo)來(lái)說(shuō)更可讀。
其語(yǔ)法是 ?
: const re = /(?d{4})-(? d{2})-(? d{2})/; const [match, year, month, day] = re.exec("2020-03-04"); console.log(match); // → 2020-03-04 console.log(year); // → 2020 console.log(month); // → 03 console.log(day); // → 04 也可以在正則表達(dá)式中,通過(guò)下標(biāo) 1 直接使用之前的捕獲組,比如:
解釋一下,1 代表 (ww) 匹配的內(nèi)容而非 (ww) 本身,所以當(dāng) (ww) 匹配了 "ab" 后,1 表示的就是對(duì) "ab" 的匹配了。console.log(/(ww)1/.test("abab")); // → true // if the last two letters are not the same // as the first two, the match will fail console.log(/(ww)1/.test("abcd")); // → false對(duì)于命名捕獲組,可以通過(guò) k
的語(yǔ)法訪問(wèn),而不需要通過(guò) 1 這種下標(biāo): 下標(biāo)和命名可以同時(shí)使用。const re = /(?2.3. s (dotAll) Flagw+)s+k /; const match = re.exec("I"m not lazy, I"m on on energy saving mode"); console.log(match.index); // → 18 console.log(match[0]); // → on on 雖然正則中 . 可以匹配任何字符,但卻無(wú)法匹配換行符。因此聰明的開(kāi)發(fā)者們用 [wW] 巧妙的解決了這個(gè)問(wèn)題。
然而這終究是個(gè)設(shè)計(jì)缺陷,在 ES2018 支持了 /s 模式,這個(gè)模式下,. 等價(jià)于 [wW]:
console.log(/./s.test(" ")); // → true console.log(/./s.test(" ")); // → true2.4. Unicode Property Escapes正則支持了更強(qiáng)大的 Unicode 匹配方式。在 /u 模式下,可以用 p{Number} 匹配所有數(shù)字:
u 修飾符可以識(shí)別所有大于 0xFFFF 的 Unicode 字符。const regex = /^p{Number}+$/u; regex.test("231???"); // true regex.test("???"); // true regex.test("ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ"); // truep{Alphabetic} 可以匹配所有 Alphabetic 元素,包括漢字、字母等:
const str = "漢"; console.log(/p{Alphabetic}/u.test(str)); // → true // the w shorthand cannot match 漢 console.log(/w/u.test(str)); // → false終于有簡(jiǎn)便的方式匹配漢字了。2.5. 兼容表可以到 原文 查看兼容表,總體上只有 Chrome 與 Safari 支持,F(xiàn)irefox 與 Edge 都不支持。所以大型項(xiàng)目使用要再等幾年。
3. 精讀文中列舉的四個(gè)新特性是 ES2018 加入到正則中的。但正如兼容表所示,這些特性基本還都不能用,所以不如我們?cè)贉亓?xí)一下 ES6 對(duì)正則的改進(jìn),找一找與 ES2018 正則變化的結(jié)合點(diǎn)。
3.1. RegExp 構(gòu)造函數(shù)優(yōu)化當(dāng) RegExp 構(gòu)造函數(shù)第一個(gè)參數(shù)是正則表達(dá)式時(shí),允許指定第二個(gè)參數(shù) - 修飾符(ES5 會(huì)報(bào)錯(cuò)):
new RegExp(/book(?=s)/giu, "iu");不痛不癢的優(yōu)化,,畢竟大部分時(shí)間構(gòu)造函數(shù)不會(huì)這么用。
3.2. 字符串的正則方法將字符串的 match()、replace()、search、split 方法內(nèi)部調(diào)用時(shí)都指向到 RegExp 的實(shí)例方法上,比如
String.prototype.match 指向 RegExp.prototype[Symbol.match]。
也就是正則表達(dá)式原本應(yīng)該由正則實(shí)例觸發(fā),但現(xiàn)在卻支持字符串直接調(diào)用(方便)。但執(zhí)行時(shí)其實(shí)指向了正則實(shí)例對(duì)象,讓邏輯更為統(tǒng)一。
舉個(gè)例子:
"abc".match(/abc/g) / // 內(nèi)部執(zhí)行時(shí),等價(jià)于 abc / g[Symbol.match]("abc");3.3. u 修飾符概述中,Unicode Property Escapes 就是對(duì) u 修飾符的增強(qiáng),而 u 修飾符是在 ES6 中添加的。
u 修飾符的含義為 “Unicode 模式”,用來(lái)正確處理大于 uFFFF 的 Unicode 字符。
同時(shí) u 修飾符還會(huì)改變以下正則表達(dá)式的行為:
點(diǎn)字符原本支持單字符,但在 u 模式下,可以匹配大于 0xFFFF 的 Unicode 字符。
將 u{61} 含義由匹配 61 個(gè) u 改編為匹配 Unicode 編碼為 61 號(hào)的字母 a。
可以正確識(shí)別非單字符 Unicode 字符的量詞匹配。
S 可以正確識(shí)別 Unicode 字符。
u 模式下,[a-z] 還能識(shí)別 Unicode 編碼不同,但是字型很近的字母,比如 u212A 表示的另一個(gè) K。
基本上,在 u 修飾符模式下,所有 Unicode 字符都可以被正確解讀,而在 ES2018,又新增了一些 u 模式的匹配集合來(lái)匹配一些常見(jiàn)的字符,比如 p{Number} 來(lái)匹配 ?。
3.4. y 修飾符y 修飾符是 “粘連”(sticky)修飾符。
y 類似 g 修飾符,都是全局匹配,也就是從上次成功匹配位置開(kāi)始,繼續(xù)匹配。y 的區(qū)別是,必須是上一次匹配成功后的下一個(gè)位置就立即匹配才算成功。
比如:
/a+/g.exec("aaa_aa_a"); // ["aaa"]3.5. flags通過(guò) flags 屬性拿到修飾符:
const regex = /[a-z]*/gu; regex.flags; // "gu"4. 總結(jié)本周精讀借著 regexp-features-regular-expressions 這篇文章,一起理解了 ES2018 添加的正則新特性,又順藤摸瓜的整理了 ES6 對(duì)正則做的增強(qiáng)。
如果你擅長(zhǎng)這種擴(kuò)散式學(xué)習(xí)方式,不妨再進(jìn)一步溫習(xí)一下整個(gè) ES6 引入的新特性,筆者強(qiáng)烈推薦阮一峰老師的 ECMAScript 6 入門 一書。
ES2018 引入的特性還太新,單在對(duì) ES6 特性的使用應(yīng)該和對(duì) ES3 一樣熟練。
如果你身邊的小伙伴還對(duì) ES6 特性感到驚訝,請(qǐng)把這篇文章分享給他,防止退化為 “只剩項(xiàng)目經(jīng)驗(yàn)的 JS 入門者”。
討論地址是:精讀《正則 ES2018》 · Issue #127 · dt-fe/weekly如果你想?yún)⑴c討論,請(qǐng)點(diǎn)擊這里,每周都有新的主題,周末或周一發(fā)布。前端精讀 - 幫你篩選靠譜的內(nèi)容。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/101787.html
摘要:舉例來(lái)說(shuō)即便某個(gè)失敗了,也不會(huì)導(dǎo)致的發(fā)生,這樣在不在乎是否有項(xiàng)目失敗,只要拿到都結(jié)束的信號(hào)的場(chǎng)景很有用。對(duì)于則稍有不同只要有子項(xiàng),就會(huì)完成,哪怕第一個(gè)了,而第二個(gè)了,也會(huì),而對(duì)于,這種場(chǎng)景會(huì)直接。 1. 引言 本周精讀的內(nèi)容是:Google I/O 19。 2019 年 Google I/O 介紹了一些激動(dòng)人心的 JS 新特性,這些特性有些已經(jīng)被主流瀏覽器實(shí)現(xiàn),并支持 polyfill...
摘要:目前我們的業(yè)務(wù)項(xiàng)目采用的來(lái)進(jìn)行優(yōu)化和首屏性能提升。可變性需要讓開(kāi)發(fā)人員降低開(kāi)發(fā)時(shí)的基準(zhǔn)線,來(lái)保證每一個(gè)用戶的體驗(yàn)。對(duì)于路由的切分以及庫(kù)的引入來(lái)說(shuō),這一個(gè)原則至關(guān)重要??焖偕梢环菡军c(diǎn)的性能審查報(bào)告。 The Cost Of JavaScript 2018 關(guān)于原文 原文是在Medium上面看到的,Chrome工程師Addy Osmani發(fā)布的一篇文章,這位的Medium上面的自我介紹里...
摘要:解析可以分為如下四步詞法分析,將字符串拆分成包含關(guān)鍵詞識(shí)別的字符段。涉及到語(yǔ)意處理就要考慮上下文,而這都不是詞法分析階段要考慮的。更多討論討論地址是精讀手寫編譯器詞法分析如果你想?yún)⑴c討論,請(qǐng)點(diǎn)擊這里,每周都有新的主題,周末或周一發(fā)布。 1 引言 因?yàn)楣ぷ麝P(guān)系,需要開(kāi)發(fā)支持眾多方言的 SQL 編輯器,所以復(fù)習(xí)了一下編譯原理相關(guān)知識(shí)。 相比編譯原理專家,我們只需要了解部分編譯原理即可實(shí)現(xiàn) ...
摘要:引言是一個(gè)版語(yǔ)法解析器生成器,具有分詞語(yǔ)法樹解析的能力。實(shí)現(xiàn)函數(shù)用鏈表設(shè)計(jì)函數(shù)是最佳的選擇,我們要模擬調(diào)用棧了。但光標(biāo)所在的位置是期望輸入點(diǎn),這個(gè)輸入點(diǎn)也應(yīng)該參與語(yǔ)法樹的生成,而錯(cuò)誤提示不包含光標(biāo),所以我們要執(zhí)行兩次。 1. 引言 syntax-parser 是一個(gè) JS 版語(yǔ)法解析器生成器,具有分詞、語(yǔ)法樹解析的能力。 通過(guò)兩個(gè)例子介紹它的功能。 第一個(gè)例子是創(chuàng)建一個(gè)詞法解析器 my...
摘要:嵌套對(duì)象成員會(huì)造成重大性能影響盡量少用。一般來(lái)說(shuō)你可以通過(guò)這種方法提高代碼的性能將經(jīng)常使用的對(duì)象成員數(shù)組項(xiàng)和域外變量存入局部變量中。在反復(fù)訪問(wèn)的地方使用局部變量存放引用小心地處理集合因?yàn)樗麄儽憩F(xiàn)出存在性總是對(duì)底層文檔重新查詢。 前言 本期我來(lái)給大家推薦的書是《高性能JavaScript》,在這本書中我們能夠了解 javascript 開(kāi)發(fā)過(guò)程中的性能瓶頸,如何提升各方面的性能,包括代碼...
閱讀 1272·2021-09-30 09:47
閱讀 3839·2021-09-06 15:02
閱讀 1851·2021-09-01 10:46
閱讀 2428·2019-08-30 15:52
閱讀 697·2019-08-29 15:28
閱讀 1928·2019-08-29 15:08
閱讀 1224·2019-08-29 13:28
閱讀 2627·2019-08-29 12:19