這是一篇男女老幼入門精通咸宜的正則筆記

未經容許,請勿私自轉載正則表達式

前言

說句實話的,自從我整理這篇筆記後,基本上項目裏遇到的全部正則匹配的問題,不論多複雜,只要回過頭看這篇筆記,理解透徹(請注意個人用詞描述,我這裏描述比較嚴謹,理解好中文意思更方便你理解正則意義。這是個文字遊戲[奸笑]),基本上都能解決的。這裏關於深內容的描述,我這邊也舉了很多內容幫助你們理解。express

這是一篇男女老幼入門精通咸宜的正則筆記。數組

正則表達式是什麼?

字符是計算機軟件處理文字時最基本的單位,字符串是0個或更多個字符的序列。 在編寫處理字符串的程序或網頁時,常常會有查找符合某些複雜規則的字符串的須要。正則表達式就是用於描述這些規則的工具,就是來用於匹配字符串中字符組合的模式。瀏覽器

怎麼建立?

正則表達式字面量
/ pattern / flag
調用RegExp對象的構造函數
new RegExp(pattern, flag)
這裏的pattern,有三種形式:bash

  1. 參數變量
  2. 帶引號的匹配模式
  3. 帶//的匹配模式

注意:帶引號的方式,須要常規的字符轉義規則(在前面加反斜槓 \),而帶//的方式,則跟字面量形式同樣。函數

E.g. 都表示同一個規則工具

var re = new RegExp("\\w+");
var re = new RegExp(/\w+/);
var re = /\w+/;
複製代碼

flag標識

若是指定,標誌能夠具備如下值的任意組合:測試

g : 全局匹配;找到全部匹配,而不是在第一個匹配後中止ui

i : 忽略大小寫spa

m : 多行; 將開始和結束字符(^和$)視爲在多行上工做(例如,分別匹配每一行的開始和結束(由 \n 或 \r 分割),而不僅是隻匹配整個輸入字符串的最開始和最末尾處。

區別:
當正則表達式保持爲常量時使用字面量;若是你知道正則表達式模式將會改變,或者你事先不知道什麼模式,而是從另外一個來源獲取,如用戶輸入,這些狀況均可以使用構造函數。

規則

簡單匹配,精確匹配
常見的特殊字符

特殊字符 描述
\b 匹配一個詞的邊界。\b匹配這樣的位置:它的前一個字符和後一個字符不全是(一個是,一個不是或不存在)\w。注意,一個匹配的詞的邊界並不包含在匹配的內容中,跟^$同樣,或者能夠這麼理解:因爲這是個位置,因此匹配出來天然就沒東西了。
舉例說明:
一個字符串reading books,\b匹配的是哪裏呢?畫個圖,看錶格最下方圖一。就是橙色線的位置就是\b的位置了
\w 匹配一個單字字符(字母、數字或者下劃線)
\s 匹配一個空白字符,包括空格、製表符、換頁符和換行符。
\d 匹配一個數字。匹配的是正整數,且匹配檢查的對象是數字類型時,如1. 會當成1 處理,即/^\d$/.test(1.)返回true,/^\d$/.test(‘1.’)返回false;
. (小數點)匹配除換行符以外的任何單個字符。
[\u4e00-\u9fa5] 匹配漢字
匹配前面一個表達式0次或者1次。等價於 {0,1}。若是緊跟在任何量詞 *、 +、?或 {} 的後面,將會使量詞變爲非貪婪的(匹配儘可能少的字符),和缺省使用的貪婪模式(匹配儘量多的字符)正好相反。
* 匹配前一個表達式0次或屢次。等價於 {0,}。
+ 匹配前面一個表達式1次或者屢次。等價於 {1,}。
{n} n是一個正整數,匹配了前面一個字符恰好發生了n次

{n,m}

n 和 m 都是正整數。匹配前面的字符至少n次,最多m次。若是 n 或者 m 的值是0, 這個值被忽略。
^ 匹配輸入的開始。若是多行標誌被設置爲true,那麼也匹配換行符後緊跟的位置。當'^'做爲第一個字符出如今一個字符集合模式時,它將表示「非」
$ 匹配輸入的結束。若是多行標示被設置爲true,那麼也匹配換行符前的位置。
| x|y,匹配‘x’或者‘y’。匹配分枝條件時,將會從左到右地測試每一個條件,若是知足了某個分枝的話,就不會去再管其它的條件了。
[ ] 一個字符集合。匹配方括號的中任意字符,包括轉義序列。你可使用破折號(-)來指定一個字符範圍。不過[.?!*]匹配標點符號(.或?或!或*)。他們沒必要進行轉義,不過轉義也是起做用的。
[^] 當 '^'做爲第一個字符出如今一個字符集合模式時,它將表示「非」。並且是對於其後的全部表達式取非,而不是緊接其後的一個表達式。 匹配的結果爲不是這些字符的字符。
[^aei]匹配除了aei這幾個字母之外的任意字符,注意是單獨取非,即不能出現a或e或i,而不是不能出現aei這個總體字符串。
例如:/[^aei]/.test('a'),結果爲false,由於他出現了a。再如/[^aei]/.test('as'),結果爲true,由於這裏的有出現s,知足既不爲a也不爲e也不爲i。
\ 在非特殊字符以前的反斜槓表示下一個字符是特殊的,不能從字面上解釋。反斜槓也能夠將其後的特殊字符,轉義爲字面量。使用 new RegExp("pattern")的時候不要忘記將 \ 進行轉義,由於 \ 在字符串裏面也是一個轉義字符。

此外,對應還有\B \W \S \D,都匹配跟上面小寫的意思相反

正則表達式裏的單詞是什麼意思吧:就是很多於一個的連續的\w。


圖一:

「(」和「)」也是元字符,須要時也是要使用轉義的。

規則 描述
(x) 使用小括號指定一個子表達式後,匹配這個子表達式的文本(也就是此分組捕獲的內容)能夠在表達式或其它程序中做進一步的處理。
(?:x) 匹配 'x'可是不記住匹配項。這種叫做非捕獲括號,不給此分組分配組號

(?x)

匹配x,並捕獲文本到名稱爲name的組裏,也能夠寫成 (?'name'x)

這裏詳細說說關於 (x)

默認狀況下,每一個分組會自動擁有一個組號,規則是:分組0對應整個正則表達式實際上組號分配過程是要從左向右掃描兩遍的:第一遍只給未命名組分配,第二遍只給命名組分配--所以全部命名組的組號都大於未命名的組號

可使用(?:exp)這樣的語法來剝奪一個分組對組號分配的參與權。

後向引用用於重複搜索前面某個分組匹配的文本。
例如,\1表明分組1匹配的文本。

注意:
這個不適合對「範圍值」使用,即不能一看就知道是表明哪一個字符的狀況使用,如\d\w或利用中括號表示某些範圍的值等狀況,由於你用\d來判斷時,此刻你不知道\d表明具體哪一個數字。假如你仍然對這些「範圍值」使用後向引用的話,引用的值必須跟第一次出現的值要如出一轍。
例如,/^([a-z\d])\1$/,能夠是字母也可數字,可是第一次出現的數字的話,後面必須也是數字,且必須是同一個數字,這個表達式纔會匹配出true

這個例子去運行一下就知道應用場景和意義了:'2018-09-87'.match(/^(\d{1,4})(-|/)(\d{1,2})\2(\d{1,2})$/)

零寬斷言

即零寬度斷言,斷言就是判斷條件,零寬度就是匹配出來的內容是零,表現跟上述的\b^$同樣,也是用來匹配位置的。

規則 描述

(?=x)

匹配這麼一個位置:後面接着出現的是匹配表達式x。
好比\b\w+(?=ing\b),匹配以ing結尾的單詞的前面部分(除了ing之外的部分)。 如查找I'm singing while you're dancing.時,它會匹配sing和danc。
如表格下放的圖二所示,因此匹配出來的結果是橙線和藍線之間的內容,即上述表達的\w+部分
(?<=x) 匹配這麼一個位置:前面接着出現的是匹配表達式x。
好比(?<=\bre)\w+\b會匹配以re開頭的單詞的後半部分(除了re之外的部分),例如在查找reading a book時,它匹配ading。如表格下放的圖三所示
(?!x) 匹配這麼一個位置:後面接着出現的不能是匹配表達式x。
例如:\d{3}(?!\d)匹配三位數字,並且這三位數字的後面不能是數字
(?<!x) 匹配這麼一個位置:前面接着出現的不能是匹配表達式x。

圖二:

圖三:


這裏有兼容性問題,有些瀏覽器只支持正向的零寬斷言即(?=exp)和(?!exp),不支持負向零寬斷言。並且就算瀏覽器支持了,可能你的編譯工具在運行編譯時也會報錯。

值得一提,有個經典的用法,也是運用到零寬斷言,假設有個需求須要匹配一個字符串裏不能包含某個字符串。例如,判斷一個字符串裏不能包含hello
正則表達式: ^((?!hello).)*$
若是用test()來校驗的話,那麼只要這個字符串裏包含hello,就會爲false。固然其實這種需求並不須要這麼麻煩去處理。直接用/hello/.test(somestring),而後取反就能識別了。

貪婪與懶惰

當正則表達式中包含能接受重複的限定符時,一般的行爲是(在使整個表達式能獲得匹配的前提下)匹配儘量多的字符。

以這個表達式爲例:a.*b,它將會匹配最長的以 a開始,以b結束的字符串。若是用它來搜索aabab的話,它會匹配整個字符串aabab。這被稱爲貪婪匹配。

有時,咱們更須要懶惰匹配,也就是匹配儘量少的字符。前面給出的限定符均可以被轉化爲懶惰匹配模式,只要在它後面加上一個問號?。
這樣.*?就意味着匹配任意數量的重複,可是在能使整個匹配成功的前提下使用最少的重複。

a.*?b匹配最短的,以a開始,以b結 束的字符串。若是把它應用於aabab的話,它會匹配aab(第一到第三個字符)和ab(第四到第五個字符)。 爲何第一個匹配是aab(第一到第三個字符)而不是ab(第二到第三個字符)?

簡單地說,由於正則表達式有另 一條規則,比懶惰/貪婪規則的優先級更高:** 最早開始的匹配擁有最高的優先權。**
懶惰模式適用於 * ? + {} 後面;

還有一個很好例子說明懶惰模式的用處,'{{f}},fas{{fsfsf}}a{{fsa}}'.match(/{{.+?}}/g)。 這個就能把一個字符串裏全部{{}}的最小單位給篩選出來,能夠去控制檯裏輸出看看

怎麼用?

被用於 RegExp 的 exec 和 test 方法, 以及 String 的 match、replace、search 和 split 方法。

exec()

語法
regexObj.exec(str)
返回值
若是匹配成功,exec()方法返回一個數組,並更新正則表達式對象的屬性。返回的數組將徹底匹配成功的文本做爲第一項,將正則括號裏匹配成功(即括號捕獲)的做爲數組填充到後面。
若是匹配失敗,exec() 方法返回 null。

test()

語法
regexObj.test(str)
返回值
若是正則表達式與指定的字符串匹配,返回true;不然false。

search()

語法
str.search(regexp)
參數regexp,一個正則表達式(regular expression)對象。若是傳入一個非正則表達式對象,則會使用 new RegExp(obj)隱式地將其轉換爲正則表達式對象。
返回值
若是匹配成功,則search()返回正則表達式在字符串中首次匹配項的索引。不然,返回 -1。

match()

語法
str.match(regexp);
參數regexp,一個正則表達式對象。若是傳入一個非正則表達式對象,則會隱式地使用 new RegExp(obj) 將其轉換爲一個RegExp。若是你未提供任何參數,直接使用 match() ,那麼你會獲得一個包含空字符串的 Array :[""] 。
返回值
一個包含了整個匹配結果以及任何括號捕獲的匹配結果的 Array ;若是沒有匹配項,則返回 null 。
描述
若是正則表達式沒有 g 標誌,則str.match()會返回和 RegExp.exec()相同的結果。
相比有g,返回的Array擁有一個額外的input屬性,該屬性包含被解析的原始字符串。另外,還擁有一個index屬性,該屬性表示匹配結果在原字符串中的索引(以0開始)。

若是正則表達式包含 g 標誌,則該方法返回一個 Array ,它包含全部匹配的子字符串而不是匹配對象。捕獲組不會被返回(即不返回index屬性和input屬性)。若是沒有匹配到,則返回 null 。

注意

  1. 只有用match方法才能體現g的意義
  2. 注意返回值,其中有個描述是會返回括號捕獲結果,這個信息很是重要。舉個例子說明其重要性:針對這麼一個字符串CrawlerName":"BW","Sis":444',獲取「BW」這個字符串。若是用正則匹配出來?

第一反應,使用上述的零寬斷言,運行一下腳本

'"CrawlerName":"BW","Sis":444'.match(/(?<="CrawlerName":").*(?=",)/)
複製代碼

返回值爲一個數組—— ['BW']

然而,可能瀏覽器不支持負向零寬斷言,因此找個通用的辦法,這時候就要發揮match返回括號捕獲的功能了。運行一下腳本

'"CrawlerName":"BW","Sis":444'.match(/"CrawlerName":"(.*)",/)
複製代碼

這時候返回['"CrawlerName":"BW",', 'BW'],你們注意到第二個元素了沒,就是括號捕獲的內容了,是否是比用零寬斷言簡單好多咧

最後

若是你有正則匹配問題,歡迎諮詢,儘可能爲你解答。

喜歡請點贊~~寫文章不易,用手機寫的,若有格式問題請諒解

未經容許,請勿私自轉載

相關文章
相關標籤/搜索