JavaScript正規表示式進階指南

mug發表於2021-09-09

摘要: 正規表示式是程式設計師的必備技能,想不想多學幾招呢?

JavaScript正規表示式進階指南

本文用JavaScript的exec方法來測試正規表示式。

例如,正規表示式/F.*g/會匹配“以F開頭,以g結尾的字串”,因此可以匹配"Hello, Fundebug!"中的Fundebug,exec方法會返回一個陣列,其第一個元素為所匹配的子字串。

/F.*g/.exec("Hello, Fundebug!")[0]
// 'Fundebug'
複製程式碼

非貪婪匹配

預設情況下,正規表示式的量詞***、+、?、{},都是進行貪婪匹配,即匹配儘可能多的字元**。

例如,正規表示式/.+\s/匹配的是“以空格符結尾的字串”,我們用它來匹配蘋果公司創始人賈伯斯在史丹佛大學演講的名言“You time is limited, so don’t waste it living someone else’s life.”:

/.+\s/.exec("You time is limited, so don’t waste it living someone else’s life.")[0]
// 'You time is limited, so don’t waste it living someone else’s '
複製程式碼

.可以匹配任意字元,而+表示匹配1次或者多次,且是貪婪的,因此/.+\s/匹配到了最後一個空格符才結束。

當我們在量詞、+、?、{}後面緊跟著一個?,就可以實現非貪婪匹配,即匹配儘量少的字元

例如,正規表示式/.+?\s/匹配到第一個空格符就會結束:

/.+?\s/.exec("You time is limited, so don’t waste it living someone else’s life.")[0]
// 'You '
複製程式碼

正向肯定查詢

使用正規表示式x(?=y),可以匹配'x'僅僅當'x'後面跟著'y'。這話有點繞,簡單地說,就是匹配後面是y的x,這裡的x和y都代表正規表示式。

例如,對於部落格RabbitMQ入門教程的地址"blog.fundebug.com/2018/04/20/…",如果需要匹配出域名fundebug的話,可以使用/[a-z]+(?=\.com)/,匹配“在.com前面的英文單詞”

/[a-z]+(?=\.com)/.exec("https://blog.fundebug.com/2018/04/20/rabbitmq_tutorial/")[0]
// 'fundebug'
複製程式碼

廣告:歡迎免費試用Fundebug,為您監控線上程式碼的BUG,提高使用者體驗~

正向否定查詢

與正向肯定查詢所對應的是正向否定查詢,使用正規表示式x(?!y),可以"匹配'x'僅僅當'x'後面不跟著'y'"。

例如,小學生都知道的圓周率是3.1415926,不會的同學可以這樣記“山頂上有一座寺廟,寺廟裡面有一壺酒,還有一塊肉”。如何匹配小數點後面的數字呢?可以使用/\d+(?!\\.)/,匹配"後面沒有小數點的數字":

/\d+(?!\.)/.exec("3.1415926")[0]
// '1415926'
複製程式碼

而使用之前提到的正向肯定查詢,就可以匹配小數點前面的數字:

/\d+(?=\.)/.exec("3.1415926")[0]
// '3'
複製程式碼

多行匹配

下面是鮑勃·迪倫的《Forever Young》歌詞:

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.+/是錯誤的:

/^forever.+/.exec("May God bless and keep you always,\nmay your wishes all come true,\nmay you always do for others\nand let others do for you.\nmay you build a ladder to the stars\nand climb on every rung,\nmay you stay forever young,\nforever young, forever young,\nMay you stay forever young.")
// null
複製程式碼

為什麼錯了?因為^匹配的整個字串的開始,而是不是每一行的開始。

正規表示式指定m選項,即可支援多行匹配,這時^$匹配的是每一行的開始和結束,因此正確的正規表示式是**/^forever.+/m**:

/^forever.+/m.exec("May God bless and keep you always,\nmay your wishes all come true,\nmay you always do for others\nand let others do for you.\nmay you build a ladder to the stars\nand climb on every rung,\nmay you stay forever young,\nforever young, forever young,\nMay you stay forever young.")[0]
// 'forever young, forever young,'
複製程式碼

捕獲括號

在正規表示式中使用小括號(),可以提取出字串中的特定子串。

例如,Fundebug是在2016年雙11正式上線的,時間是"2016-11-11",如何提取其中的年、月、日呢?如下:

/(\d{4})-(\d{2})-(\d{2})/.exec("2016-11-11")
// [ '2016-11-11', '2016', '11', '11', index: 0, input: '2016-11-11' ]
複製程式碼

可知,3個小括號中的正規表示式分別匹配的是年月日,其結果依次為exec返回陣列中的1到3號元素。

參考

關於Fundebug

Fundebug專注於JavaScript、微信小程式、微信小遊戲、支付寶小程式、React Native、Node.js和Java實時BUG監控。 自從2016年雙十一正式上線,Fundebug累計處理了9億+錯誤事件,得到了Google、360、金山軟體、百姓網等眾多知名使用者的認可。歡迎免費試用!

JavaScript正規表示式進階指南

版權宣告

轉載時請註明作者Fundebug以及本文地址:
blog.fundebug.com/2018/05/02/…

相關文章