摘要:如字段,使用,會匹配出使用,會匹配出元字符在正則表達式中有一些具有特殊含義的字母,被稱為元字符,簡言之,元字符就是描述字符的字符,它用于對字符表達式的內容轉換及各種操作信息進行描述。
關于正則表達式的教程網上實在太多,但都不太友好,在此我整理一篇,面向自己行文。
學正則需要記語法,最好的方式無非就是實操,邊寫邊學,因此第一步,推薦一個在線工具:
在線工具regex101
正則的在線工具只推薦regex101,解釋正則表達式、顯示匹配信息、提供常用語法參考等,足夠強大和界面友好。
基礎知識下面開始正式內容,在 Javascript 中,一個正則表達式以 / 開頭和結尾,所以 /hello regexp/ 就是一個正則表達式。
正則中有幾個大類需要了解:Flags、Character Sets、Quantifiers、Metacharacters、Special Characters、Groups、Assertion,下面我們一一來講解。
Flags(標志符或修飾符)Flags 寫在結束的/之后,可以影響整個正則表達式的匹配行為。常見的 flags 有:
g:全局匹配(global);正則表達式默認只會返回第一個匹配結果,使用標志符 g 則可以返回所有匹配。
i:忽略大小寫(case-insensitive);在匹配時忽略英文字母的大小寫。
m:多行匹配(multiline);將開始和結束字符(^和$)視為在多行上工作,即分別匹配每一行(由 n 或 r 分割)的開始和結束,而不只是只匹配整個輸入字符串的最開始和最末尾處。
所有的 flags 都打上的話,那就是/^*$/gimsuy:
用于匹配字符集合中的任意一個字符。
[xyz]:匹配 x或y或z。
[^xyz]:補集,匹配除了 x y z的其他字符。
[a-z]:匹配從 a 到 z 的任意字符。
[^a-n]:補集,匹配除了 a 到 n 的其他字符。
[A-Z]:匹配從 A 到 Z 的任意字符。
[0-9]:匹配從 0 到 9 的任意數字。
匹配所有的字母和數字可寫成:/[a-zA-Z0-9]/ 或者 /[a-z0-9]/i。
Quantifiers (量詞)使用 Quantifiers 來實現重復匹配。
{n}:匹配 n 次。
{n,m}:匹配 n到m 次。
{n,}:匹配 >=n 次,即大于n次。
?:匹配 0 || 1 次,即 0或者1 次。
*:匹配 >=0 次,等價于 {0,}。
+:匹配 >=1 次,等價于 {1,}。
如字段abczzzzzzzxyabcabcabc,使用/z*xy/gi,會匹配出zzzzzzzxy;
使用/z{0,2}xy/gi,會匹配出zzxy;
Metacharacters(元字符)在正則表達式中有一些具有特殊含義的字母,被稱為元字符,簡言之,元字符就是描述字符的字符,它用于對字符表達式的內容、轉換及各種操作信息進行描述。
常見的元字符有:
d:匹配任意數字,等價于 [0-9]。
D:匹配任意非數字字符;d 的補集。
w:匹配任意基本拉丁字母表中的字母和數字,以及下劃線;等價于 [A-Za-z0-9_]。
W:匹配任意非基本拉丁字母表中的字母和數字,以及下劃線;w 的補集。
s:匹配一個空白符,包括空格、制表符、換頁符、換行符和其他 Unicode 空格。
S:匹配一個非空白符;s 的補集。
:匹配一個零寬單詞邊界,如一個字母與一個空格之間;例如,/no/匹配 at noon 中的 no,/ly/ 匹配 possibly yesterday. 中的 ly。
B:匹配一個零寬非單詞邊界,如兩個字母之間或兩個空格之間;例如,/Bon/ 匹配 at noon 中的 on,/yeB/ 匹配 possibly yesterday. 中的 ye。
:匹配一個水平制表符(tab)。
:匹配一個換行符(newline)。
:匹配一個回車符(carriage return)。
理解 零寬單詞邊界我們看以下的匹配:
上圖中,紫紅色豎線表示的位置就是零寬單詞邊界(Matches a zero-width word boundary),說白了,就是一個字母的兩側是否有空格,我們輸入內容,就知道匹配的是什么了:
Special Characters (特殊字符)正則中存在一些特殊字符,它們不會按照字面意思進行匹配,而有特殊的意義,比如前文講過用于量詞的?、*、+。
其他常見的特殊字符有:
:轉義字符,可以將普通字符轉成特殊字符。比如w;也可以將特殊字符轉成字面意思,比如 + 匹配 +。
.:匹配任意單個字符,但是換行符除外: , , u2028 或 u2029;在字符集中[.],無特殊含義,即表示 . 的字面意思。
|:替換字符(alternate character),匹配 | 前或后的表達式。比如需要同時匹配 bear 和 pear,可以使用 /(b|p)ear/ 或者 /bear|pear/;但是不能用 /b|pear/,該表達式只能匹配 b 和 pear。
^:匹配輸入的開始。比如,/^A/ 不匹配 an Apple 中的 A,但匹配 An apple 中的 A。
$:匹配輸入的結尾。比如,/t$/ 不匹配 eater 中的 t,但匹配 eat 中的 t。
^ 和 $ 在表單驗證時常需要使用,因為需要驗證從開始到結尾的一個完整輸入,而不是匹配輸入中的某一段。
Groups(分組)(xyz):捕獲分組(Capturing Group),匹配并捕獲匹配項;例如,/(foo)/ 匹配且捕獲 foo bar. 中的 foo。
被匹配的子字符串可以在結果數組的元素 [1], ..., [n] 中找到,或在被定義的 RegExp 對象的屬性 $1, ..., $9 中找到。
(?:xyz):非捕獲分組(Non-capturing Group),匹配但不會捕獲匹配項;匹配項不能再次被訪問到。
:n 是一個正整數,表示反向引用(back reference),指向正則表達式中第 n 個括號(從左開始數)中匹配的子字符串;例如,/apple(,)sorange1/ 匹配 apple, orange, cherry, peach. 中的 apple, orange,。
我們來理解一下:“非捕獲分組(Non-capturing Group)”是什么意思?先執行如下代碼:
var string = "at noonfooasfodsoo"; var regex = /(foo)/gi; var c1 = regex.exec(string); var regex1 = /(?:foo)/gi; var c2 = regex1.exec(string);
看看輸出結果c1和c2值的區別:
返回的數組中少了[1]的內容,我們到 regex101 上去也看看區別:
所以使用(?:xyz),意思是匹配并但不會捕獲匹配項到 Group 中。
我們再來理解什么是“反向引用(back reference)”如上例,/apple(,)sorange1/中的1指的其實就是(,),這個表達式等同的寫法是/apple(,)sorange(,)/
我們試試2,也就是等價于左數第二個括號中的內容,看看匹配到的內容,我們在文本內容中再多加一個,:
x(?=y):僅匹配被 y 跟隨的 x,這個也被稱為:“先行斷言”/“正向肯定查找”
例如,/bruce(?=wayne)/,如果bruce后面跟著wayne,則匹配bruce。
/bruce(?=wayne|banner)/,如果bruce后面跟著wayne或者banner,則匹配bruce。
wayne 和 banner 都不會在匹配結果中出現。
(?<=y)x:匹配"x"僅當"x"前面是"y",這個也被稱為:“后行斷言”
例如,(?<=bruce)wayne,如果wayne前面是bruce,則匹配wayne。
/(?<=bruce|banner)wayne/,如果wayne前面是bruce或者banner,則匹配wayne。
wayne 和 banner 都不會在匹配結果中出現。
x(?!y):僅匹配不被 y 跟隨的 x,這個也被稱為:“正向否定查找”
例如,/d+(?!.)/ 只會匹配不被 "." 跟隨的數字。
/d+(?!.)/.exec("3.141") 匹配 141,而不是 3.141
非貪婪匹配(non-greedy)默認情況下,正則表達式的量詞*、+、?、{},都是進行貪婪匹配(greedy),即匹配盡可能多的字符。
非貪婪匹配,即匹配盡量少的字符(matching the fewest possible characters)。
怎么理解呢?
例如這么一段話:The reading of all good books is like a conversation with the finest men of past centuries.
使用/.+s/匹配,.可以匹配任意字符,而+表示匹配 1 次或者多次,默認是貪婪匹配,所以會匹配到了最后一個空格符才結束。
而當我們在量詞*、+、?、{}后面緊跟著一個?,就可以實現非貪婪匹配。
例如/.+?s/,匹配到第一個空格符就會結束:
例如下面一段文字:
May God bless and keep you always, may your wishes all come true, may you always do for others and let others do for you. may you build a ladder to the stars and climb on every rung, may you stay forever young, forever young, forever young, May you stay forever young.
如何匹配以 forever 開頭的那句歌詞forever young, forever young呢?
寫/^forever.+/是錯誤的,因為^匹配的整個字符串的開始,而是不是每一行的開始。
所以指定m選項,即可支持多行匹配,這時^和$匹配的是每一行的開始和結束,因此正確的正則表達式是/^forever.+/m:
匹配1(3/4/5/7/8)開頭的11位數字。
以 1 開頭:/^1/
第 2 位為 3、4、5、7、8 中的一個:/[34578]/ 或 /(3|4|5|7|8)/
剩余 3-11 位均為數字,并以數字結尾:/d{9}$/
組合起來即為 /^1[34578]d{9}$/ 或 /^1(3|4|5|7|8)d{9}$/,因為使用捕獲括號存在性能損失,所以推薦使用第一種寫法。
2. 匹配電子郵件標準的電子郵件組成為
每部分的格式標準為:
yourname:任意英文字母(a-z/A-Z)、數字(0-9)、下劃線(_)、英文句點(.)、連字符(-),長度大于 0
domain:任意英文字母(a-z/A-Z)、數字(0-9)、連字符(-),長度大于 0
extension:任意英文字母(a-z/A-Z),長度 2-8
optional-extension:"."開頭,后面跟任意英文字母(a-z/A-Z),長度 2-8,可選
每部分的正則表達式為:
yourname:/[a-zd._-]+/
domain:/[a-zd-]+/
extension:/[a-z]{2,8}/
optional-extension:/(.[a-z]{2,8})?/
組合起來形成最后的正則表達式:/^([a-zd._-]+)@([a-zd-]+).([a-z]{2,8})(.[a-z]{2,8})?$/ig;為了增加可讀性可以將每部分用()包起來,并不要忘記起始和結束符^$。
掌握上面所說的這些內容,日常使用的正則基本不會有什么問題了。
參考文章MDN
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/105004.html
摘要:正則表達式作為前端學習的一個知識點,是每個合格的前端開發都應該掌握它的用法。元字符一般情況下,正則表達式的一個字符對應字符串的一個字符。 正則表達式作為前端學習的一個知識點,是每個合格的前端開發都應該掌握它的用法。正則表達式的學習確實不難,語法和應用也非常簡單,能夠快速入門,很輕松的就能寫出簡單的表達式來對字符串執行某些操作。網上也有標題黨說一杯咖啡的時間就能學會。能學會嗎?能!但要真...
摘要:若要擴展功能,裝飾者提供了比繼承更有彈性的替代方案。裝飾者模式意味著一群裝飾者類,這些類用來包裝具體組件。裝飾者類反映出被裝飾組件類型。裝飾者會導致設計中出現許多小對象,如果過度使用,會讓程序變得很復雜。 嘿嘿嘿,你是不是很喜歡用繼承呢?感覺沒什么事情是一個爸爸類搞不定的,有的話就兩個,快來跟我看看這個模式吧,它能讓你斷奶,給愛用繼承的人一個全新的設計眼界。 直奔主題,你是否有聽說...
閱讀 3303·2021-11-24 09:39
閱讀 2808·2021-10-12 10:20
閱讀 1916·2019-08-30 15:53
閱讀 3080·2019-08-30 14:14
閱讀 2609·2019-08-29 15:36
閱讀 1127·2019-08-29 14:11
閱讀 1959·2019-08-26 13:51
閱讀 3414·2019-08-26 13:23