正則表達式學習筆記

正則表達式對於我來講一直像黑暗魔法同樣的存在。手機正則去網上搜,郵箱正則去網上搜,複雜點的看看文檔拼湊一下,再複雜只能厚着臉皮讓其餘同事給寫一個。歷來沒有系統的學習過,今天準備拿下它。javascript

1. 學習目標:

  1. 瞭解正則表達式語法
  2. 在IDE中使用正則表達式
  3. 在javascript 中使用正則表達式處理字符串

2. 什麼是正則表達式

正則表達式,又稱正規表示式正規表示法、正規表達式、規則表達式、常規表示法(英語:Regular Expression,在代碼中常簡寫爲regex、regexp或RE),計算機科學的一個概念。正則表達式使用單個字符串來描述、匹配一系列匹配某個句法規則的字符串。在不少文本編輯器裏,正則表達式一般被用來檢索、替換那些匹配某個模式的文本。前端

通俗的講就是按照某種規則去匹配符合條件的字符串java

3.利用圖形化工具理解正則表達式

輔助理解正則表達的在線工具 regexper.com/ 咱們利用這個工具輔助理解,正則表達式。語法沒懂表着急,後面會有,這裏只是學會用工具幫助咱們學習。git

手機號正則

/^1[34578][0-9]{9}$/正則表達式

手機號正則表達式

註釋:以1開頭,第二位爲3 4 5 7 9 其中一個,以9位(自己1次加劇復8次)0-9數字結尾segmentfault

單詞邊界

/\bis\b/後端

註釋: is先後都是單詞的邊界,比較晦澀難懂?感覺下二者的區別,\b 會方道語法部分講解api

URL分組替換

/http:(\/\/.+\.jpg)/數組

看不懂的不要慌語法部分後面會有介紹,這裏只是展現利用可視化的圖形幫助咱們理解正則表達式,能夠回來再看木有關係編輯器

正則表達式中括號用來分組,這個時候咱們能夠經過用$1來獲取 group#1的內容

說下這個正則的意義,若是網站用了https,網站引用靜態資源也必須是https,不然報錯。若是寫成 // 會自動識別 http 或者 https

日期匹配與分組替換

/^\d{4}[/-]\d{2}[/-]\d{2}$/

這個正則比較複雜,畫符唸咒的地方太多了,一一分析:

  1. Start of line 是由^生效的表示以此開頭
  2. 對應結尾End of line 由$生效表示以此結尾
  3. 接着看digit 由 \d 生效表示數字
  4. 3times 由{4} 生效表示重複4次,開始的時候有疑問,爲何不是 4times 。後來明白做者的用意,正則表達式是一個規則,用這個規則去從字符串開始匹配到結束(注意計算機讀字符串但是不會分行的,都是一個串,咱們看到的多行,人家會認爲是個 \t )這裏設計好像小火車的軌道一直開到末尾。digit 傳過一次,3times表示再來三次循環,共4次,後面的once同理。 本身被本身囉嗦到了。
  5. 接下來,是 one of 在手機正則裏面已經出現了。表示什麼都行。只要符合這兩個都讓經過。

好了這個正則解釋完了,接下來用它作什麼呢?

咱們能夠驗證日期的合法性

結合URL分組替換所用到的分組特性,咱們能夠輕鬆寫出日期格式化的方法

改造下這個正則

/^(\d{4})[/-](\d{2})[/-](\d{2})$/

輕鬆的能夠拿到 group#1 #2 #3 的內容,對應 $1 $2 $3

到如今已經能結合圖形化工具看懂正則表達式表達式了,若是想本身寫,還要在正則語法上下點功夫

4. Js中Regexp對象

Javascript 經過內置對象RegExp支持正則表達式,有兩種方法實例化RegExp對象

字面量方法

const reg =/\bis\b/g

構造函數

const reg = new RegExp('\\bis\\b', 'g')

注意:第一個參數爲正則表達式字符串(注意轉譯),第二個參數爲修飾符,修飾符g表明全局搜索,後面會有詳細介紹。

5. 正則表達式語法

1 修飾符 (三個 g i m)

修飾符與其餘語法特殊,字面量方法聲名的時候放到//後,構造函數聲明的時候,做爲第二個參數傳入。整個正則表達式能夠理解爲正則表達式規則字符串+修飾符

  • g:global 執行一個全局匹配
  • i:ignore case執行一個不區分大小寫的匹配
  • m: multiple lines多行匹配

修飾符能夠一塊兒用 const reg =/\bis\b/gim

來講說他們有什麼做用

有g和沒有g的區別

沒有g只替換了第一個,有g 全部的都換了

有i和沒有i的區別

有i忽略大小寫,沒有i嚴格區分大小寫

2 元字符

正則表達式由兩種基本字符組成:

  • 原義字符
  • 非打印字符
  • 元字符 (* + ? $ ^ . | \ ( ) { } [ ])
3. 原義字符

這個沒什麼好解釋的,咱們一直在舉例的 /is/ 匹配字符串'is'

\將下一個字符標記爲一個特殊字符、或一個原義字符、或一個向後引用、或一個八進制轉義符。例如,n」匹配字符「n」。「\n」匹配一個換行符。序列「\\」匹配「\」而「\(」則匹配「(」。

4. 非打印字符
字符 描述
\cx 匹配由x指明的控制字符。例如, \cM 匹配一個 Control-M 或回車符。x 的值必須爲 A-Z 或 a-z 之一。不然,將 c 視爲一個原義的 'c' 字符。
\f 匹配一個換頁符。等價於 \x0c 和 \cL。
\n 匹配一個換行符。等價於 \x0a 和 \cJ。
\r 匹配一個回車符。等價於 \x0d 和 \cM。
\s 匹配任何空白字符,包括空格、製表符、換頁符等等。等價於 [ \f\n\r\t\v]。
\S 匹配任何非空白字符。等價於 [^ \f\n\r\t\v]。
\t 匹配一個製表符。等價於 \x09 和 \cI。
\v 匹配一個垂直製表符。等價於 \x0b 和 \cK。

非打印字符,以\n爲例

其餘的在前端引用比較少,應該在後端處理文本文件的時候會用到

5. 字符類 []

在前面的手機號正則例子🌰中,咱們已經使用過[] /^1[34578][0-9]{9}$/ : [34578]表示34578任意一個數字便可。在日期匹配與分組替換例子🌰中 /^\d{4}[/-]\d{2}[/-]\d{2}$/ 表示符合 - 均可以

6. 字符類取反 [^]

表示不屬於此類

空格也不屬於,好多狗🐶

7. 範圍類[-]

正則表達式支持必定範圍規則好比 [a-z] [A-Z] [0-9] 能夠連寫[a-z0-9] 若是你只是想匹配-在 範圍類最後加-便可。請看實例。

8. 預約義類

經常使用爲了方便書寫

字符 等價類 含義
. [^\n\r] 除了回車符和換行符以外的全部字符
\d [0-9] 數字字符
\D [^0-9] 非數字字符
\s [\t\n\x0B\f\r] 空白符
\S [^\t\n\x0B\f\r] 非空白符
\w [a-zA-Z_0-9] 單詞字符(字母、數字、下劃線)
\W [^a-zA-Z_0-9] 非單詞字符

有了這些預約義類,寫一些正則就很方便了,好比咱們但願匹配一個 ab+數字+任意字符 的字符串,就能夠這樣寫了 /ab\d./

9. 邊界
字符 含義
^ 以xx開頭
$ 以xx結尾
\b 單詞邊界,指[a-zA-Z_0-9]以外的字符
\B 非單詞邊界

邊界顧名思義即定義匹配的邊界條件,上面基本都在前面的例子碰到了,這裏演示下\b\B 的區別

10. 量詞
字符 含義
? 出現零次或一次
* 出現零次或屢次(任意次)
+ 出現一次或屢次(至道一次)
{n} 對應零次或者n次
{n,m} 至少出現n次但不超過m次
{n,} 至少出現n次(+的升級版)
{0,n} 至多出現n次(其實就是{n,m} 方便記憶而已)

若是沒有量詞,要匹配4位數字這樣寫就能夠/\d\d\d\d/, 若是匹配50位100位呢?那不是要瘋掉了?
有了量詞,就能夠這樣寫/\d{100}/, 量詞的使用咱們在手機號中使用過,表如今可視化中就是循環多少次。

湊一個上面都包含的實例/\d?@\d*@\d+@\d{10}@\d{10,20}@\d{10,}@\d{0,10}/

11.貪婪與懶惰(非貪婪)

正則表達式默認會匹配貪婪模式,什麼是貪婪模式呢?如其名儘量多的匹配。咱們看個例子🌰。

/\d{3,6}/

貪婪模式下,匹配的了最多的狀況。

與貪婪對應就是懶惰模式,懶惰對應的就是匹配的儘量少的狀況。如何開啓懶惰模式? 在量詞後面加?。繼續上面的例子

/\d{3,6}?/

若是想知道,正則表達式是如何匹配量詞的,請看 進階正則表達式 文中有介紹,正則是如何回溯的。

12.分組與反向引用

分組,又稱爲子表達式。把正則表達式拆分紅小表達式。概念枯燥,說個例子爲嘛用分組:

不分組 /abc{2}/

量詞僅做用到最後的c

分組 /(abc){2}/

注意這裏 group #1

分組雖然和運算符() 很像,可是分組在正則表達式中,注意理解組的含義。常常有人濫用分組

/^(http|https)/ 真的須要這樣麼?其實 /^https?/就能夠了,你正則寫的特別長的時候,會出現一堆沒用的結果,看着都頭疼吧。

分組每每和反向引用一塊兒使用,別被概念嚇到:當一個正則表達式被分組後,每一個分組自動被賦予一個組號,一左到右分別是 $1 $2

再把以前的例子拿出來

/^(\d{4})[/-](\d{2})[/-](\d{2})$/

輕鬆的能夠拿到 group#1 #2 #3 的內容,對應 $1 $2 $3

若是在反向引用中不想捕獲年該如何操做? 加上 ?:便可

/^(?:\d{4})[/-](\d{2})[/-](\d{2})$/

12.前瞻

⚠️ 這部分爲進階部分—選看

正則表達式中有前瞻(Lookahead)和後顧(Lookbehind)的概念,這兩個術語很是形象的描述了正則引擎的匹配行爲。須要注意一點,正則表達式中的前和後和咱們通常理解的先後有點不一樣。一段文本,咱們通常習慣把文本開頭的方向稱做「前面」,文本末尾方向稱爲「後面」。可是對於正則表達式引擎來講,由於它是從文本頭部向尾部開始解析的(能夠經過正則選項控制解析方向),所以對於文本尾部方向,稱爲「前」,由於這個時候,正則引擎還沒走到那塊,而對文本頭部方向,則稱爲「後」,由於正則引擎已經走過了那一塊地方。

⚠️注意:後顧性能損耗比較大,js只支持前瞻(知乎上看到的,具體緣由不詳)

上面的比較概念話,嘗試用大白話講講,就說皇上選妃吧,先行條件得是美女吧,長得「如花」那樣皇上可不要,漂亮這關過了,皇上想要這個美女也不行,皇室有規矩,必須是貴族血統。

那麼「漂亮」就是正常的匹配,匹配到了,還得看看家室是否是貴族。"貴族"至關於前瞻條件

前瞻分兩種一種是正向前瞻(?=xxx), 另外一種是負向前瞻(?!xxx)

😂 是否是很簡單?那咱們來玩個好玩的。

題目:如何將'123456'轉成貨幣帶逗號的。'123,456'。這個是很常規格式化金額的需求。

若是在沒有學習正則以前,個人思路是:

  1. 字符串轉數組
  2. 反轉數組
  3. 每隔三個添加個逗號
  4. 添加完了反轉數組
  5. 數組轉字符串

好累~~~

今天學習了正則,能夠一步到位 '123456789'.replace(/(\d)(?=(?:\d{3})+$)/g, '$1,')

到此爲止正則的基本使用已經結束,後面一篇會分享一些正則的 「奇技淫巧」

相關文章
相關標籤/搜索