首頁  >  文章  >  web前端  >  JS正規表示式重點分析

JS正規表示式重點分析

小云云
小云云原創
2018-01-30 17:20:181509瀏覽

本文主要和大家分享JS正則表達式的要點,由於之前在看VueJS的源碼, 看到了HtmlParser部分, 感覺以前看的正則表達式基礎知識已經完全不夠用了, 現翻閱博客資料, 將一些JS中正規表示式難用的部分總結歸納, 方便自己和sf友翻閱.

正則分組

重複匹配

對於重複的匹配, 我們經常使用到正規表示式的分組功能, 我們使用正規匹配IP位址來實踐.

假設我們要匹配的IP位址在區間0.0.0.0 - 255.255.255.255 之間, 可以直觀的了解到, 我們只需要匹配三位數字+點號三遍, 再匹配三位數字一遍就可以了.

這裡說的三位數字+點號既是我們說的一種規則, 我們可以在表達式中將它們轉換為規則即: \d{1,3}\., 當我們把規則用括號包裝後, 就變成了群組: (\d{1,3}\ .), 所以符合IP位址的正規表示式可以寫: (\d{1,3}\.){3}\d{1,3}

換個想法, 我們也可以這樣匹配: \d{1,3}(\.\d{1,3}){3}

拓展: 聰明的你可能已經想到, \d{1,3} 匹配是有疏漏的. 在實際生產過程中, \d{1,3} 可能匹配999 這種數字, 他是錯誤的IP位址區段. 這裡貼上真實的IP位址正規符合供大家參考: ((25[0-5]|2[0-4]\d|((1\ d{2})|([1-9]?\d)))\.){3}(25[0-5]|2[0-4]\d|((1\d{2}) |([1-9]?\d))) , 另人愉快的是, 它使用的分組策略仍然是不變的.

後向引用(反向引用)

我們考慮一個很特殊的情況, 當我們要匹配四個IP段相同的情況, 如100.100.100.100 時, 重複匹配分組的策略失效了: 重複匹配分組並不能保證匹配相同的數字-> ; 這時候我們需要藉助後向引用 策略的力量了(少年, 你渴望力量嗎2333, 戳我頭像, 帶你探索音樂與代碼交織的文藝道路.)

#後向引用在不同語言的正規表示式書寫中, 有不同的語法, 我們討論JS中最常見的一種, 形如: \number 的後向引用, 其中, number 代表分組的序號.

給你一個簡單的栗子, 瞬間就記住了, 假使我們要匹配重複的三位數字, 我們將匹配一個數字的規則標記為一個分組: (\d), 重複配對這個分組(第一個分組)的具體內容三次: (\d)\1, 這樣就達到了目的.

我們很容易將重複匹配和後向引用分別開來: 前者是重複匹配相同的規則, 後者是匹配分組的具體內容.

默認的一些規則需要稍加理解並記住:

  • \0代表的是, 整個正規表示式的匹配的內容

正規斷言

還記得我看過的一篇大概名為<30分鐘學會正則表達式>的文章中, 裡面提及過正則斷言.
當時感覺真是一看就懂. 但很遺憾, 實際生產中, 使用各種複雜正則表達式的情況實在是太少, 今天如果不翻閱百度, 我恐怕是不能記起斷言的分類和各種使用方法了.

斷言的字面意思是, 斷定(程式)運行到此時(結果)是這樣的"場景", 它描述的是一種場景, 換句話說, 是一種"肯定的場景". 但要記住的是, 我們的"結果"是不包含在"場景"裡面的.

VueJS裡頭需要匹配HTML tag, 我們就以匹配: '< ;segment>Not Fault' 中的'Not Fault' 為例吧.

我們如果使用普通的正規表示式, 如/<segment>.*</segment&gt ;/ 會匹配到整個字串'Not Fault'. 我們使用斷言, 以"場景"的方式思考: '' 和''是一種"肯定的場景", 我們需要匹配的結果是: 'Not Fault', 無論tag內部的字符無論如何變化, tag頭和tag尾都是不變的.

一鼓作氣, 我們繼續往下

先行斷言

先行斷言, 我是這樣理解的: 先匹配內容, 再做"場景"假設.

放到我們先前的栗子中, 便這樣匹配, 一直匹配內容, 直到碰上'' 的場景, 語法如下: (?=</segment>)

#後發斷言

後發斷言, 我的理解是: 先匹配場景, 再匹配內容.

放到我們先前的栗子中, 先匹配'' 的場景, 再繼續往下符合內容, 語法如下: (?<=<segment>)

#實務

##正規表示式是對字串內容做比對,所以我將"先"和"後"的理解綁定到內容匹配的先後順序上, 方便理解.#

我們將先行斷言和後發斷言結合起來, 整個表達式如下: (?<=<segment>).*(?=</segment>), 我們便可得到想要的結果: 'Not Fault' 了.

"正負"斷言

#其實我們剛才做的是肯定的場景, 實際情況中還有"不滿足此場景"的使用場景.

例如, 我們剛剛使用的表達式: (?<=<segment>).*(?=</segment>) 是肯定有' ' '' 的場景下去匹配內容, 其實是使用的"正後發斷言" 和"正先行斷言", "正"即代表肯定的狀態.

那負斷言, 也就是不滿足場景的斷言咯... 語法即把正斷言中的等於號換成感嘆號:

  • #負先行斷言(?!)

  • 負後發斷言(?<!)

如: ['1999', '2099','2199'...'9099'] 中如果我們要匹配除了'1999'以外的所有帶有'99'結尾的年份, 我們可以使用表達式: (?<!19 )99

相關推薦:

JavaScript正規表示式常用基本語法

豬哥深談php正規則表達式及正規表示式都用在什麼地方?

JS基於正規表示式實作的密碼強度驗證功能範例_javascript技巧


以上是JS正規表示式重點分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn