1. 程式人生 > >正則表示式筆記,幫你打通任督二脈

正則表示式筆記,幫你打通任督二脈

前言

說句實話的,自從我整理這篇筆記後,基本上專案裡遇到的所有正則匹配的問題,不論多複雜,只要回過頭看這篇筆記,理解透徹,基本上都能解決的。這裡關於深內容的描述,我這邊也舉了不少內容幫助大家理解。

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

正則表示式是什麼?

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

怎麼建立?

正則表示式字面量
/ pattern / flag
呼叫RegExp物件的建構函式
new RegExp(pattern, flag)


這裡的pattern,有三種形式:

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

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

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

var re = new RegExp("\\w+");
var re = new RegExp(/\w+/);
var re = /\w+/;

flag標識

如果指定,標誌可以具有以下值的任意組合:

g : 全域性匹配;找到所有匹配,而不是在第一個匹配後停止

i : 忽略大小寫

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

區別:
當正則表示式保持為常量時使用字面量;如果你知道正則表示式模式將會改變,或者你事先不知道什麼模式,而是從另一個來源獲取,如使用者輸入,這些情況都可以使用建構函式。

規則

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

特殊字元 描述
\b 匹配一個詞的邊界。\b匹配這樣的位置:它的前一個字元和後一個字元不全是(一個是,一個不是或不存在)\w。注意,一個匹配的詞的邊界並不包含在匹配的內容中。換句話說,一個匹配的詞的邊界的內容的長度是0。
\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’。匹配分枝條件時,將會從左到右地測試每個條件,如果滿足了某個分枝的話,就不會去再管其它的條件了。
[ ] 一個字元集合。匹配方括號的中任意字元,包括轉義序列。你可以使用破折號(-)來指定一個字元範圍。不過[.?!*]匹配標點符號(.或?或!或*)。他們不必進行轉義,不過轉義也是起作用的。以下為所有可以在[]裡進行轉義為普通字串的字元:.[*?+^$|()/
[^] 當 '^'作為第一個字元出現在一個字元集合模式時,它將表示“非”。而且是對於其後的所有表示式整體取非,而不是緊接其後的一個表示式。 如[^aeiou]匹配除了aeiou這幾個字母以外的任意字元
\ 在非特殊字元之前的反斜槓表示下一個字元是特殊的,不能從字面上解釋。反斜槓也可以將其後的特殊字元,轉義為字面量。使用 new RegExp("pattern")的時候不要忘記將 \ 進行轉義,因為 \ 在字串裡面也是一個轉義字元。

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

正則表示式裡的單詞是什麼意思吧:就是不少於一個的連續的\w。

“(”和“)”也是元字元,需要時也是要使用轉義的。

規則 描述
(x) 使用小括號指定一個子表示式後,匹配這個子表示式的文字(也就是此分組捕獲的內容)可以在表示式或其它程式中作進一步的處理。
(?:x) 匹配 'x’但是不記住匹配項。這種叫作非捕獲括號,不給此分組分配組號
(?x) 匹配x,並捕獲文字到名稱為name的組裡,也可以寫成 (?'name’x)

這裡詳細說說關於 (x)

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

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

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

注意,這個不適合這樣使用([…]),不適合包括在方括號裡,這樣的必須後面出現的跟第一次出現的匹配型別一致。
例如,/^([a-z\d])\1$/,可以是字母也可數字,但是第一次出現的數字的話,後面必須也是數字這個表示式才會正確用。

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

零寬斷言

規則 描述
(?=x) 匹配x前面的位置,斷言自身出現的位置的後面能匹配表示式x比如\b\w+(?=ing\b),匹配以ing結尾的單詞的前面部分(除了ing以外的部分)。 如查詢I’m singing while you’re dancing.時,它會匹配sing和danc。 注意,這裡的\w是必須的,因為匹配的就是這個東西,只是這個東西匹配出來的前提條件是後面接ing。
(?<=x) 匹配x後面的位置,它斷言自身出現的位置的前面能匹配表示式x。 比如(?<=\bre)\w+\b會匹配以re開頭的單詞的後半部 分(除了re以外的部分),例如在查詢reading a book時,它匹配ading。
(?!x) 匹配後面跟的不是x的位置,斷言此位置的後面不能匹配表示式x。 例如:\d{3}(?!\d)匹配三位數字,而且這三位數字的後面不能是數字
(?<!x) 匹配前面不是x的位置,斷言此位置的前面不能匹配表示式x。

這裡有相容性問題,有些瀏覽器只支援正向的零寬斷言即(?=exp)和(?!exp),不支援負向零寬斷言

貪婪與懶惰

當正則表示式中包含能接受重複的限定符時,通常的行為是(在使整個表示式能得到匹配的前提下)匹配儘可能多的字元。

以這個表示式為例: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 。

注意:只有用match方法才能體現g的意義

最後

如果你有正則匹配問題,歡迎諮詢,儘量為你解答。

喜歡請點贊~轉載註明出處謝謝~寫文章不易

首發地----> 戳me