前言
在 Visual Studio Code 內你有沒有遇過一些情況,想要尋找(或取代)某些文字,但不知道怎麼下手。
今天來分享一個 VS Code 的小技巧,使用正規表達式(Regular Expression)來尋找和取代文字,針對一些比較複雜的情況會非常好用!!
文章我列出幾種我實際使用過的語法給各位參考。
以下技巧學起來後,未來需要尋找或取代,不用在那邊一行一行耗眼力尋找,或 ctrl+c、ctrl+v 費神練手速了。
正規表達式(Regular Expression)
先來快速認識常用的正規表達式(Regular Expression)語法:
符號 | 說明 |
---|---|
google | 匹配 google。 |
[abc] | 匹配 a 或 b 或 c 的字元。 |
[a-z] | 匹配 a~z 之間的字元。 |
[^a-z] | 匹配 所有非 a~z 之間的字元。 |
g..gle | . 代表換行字元以外的任意字元(等同於 [^\n\r] ),g 後接著兩個字元,然後接著是 gle。 |
^hello | 匹配行以 hello 開頭。 |
world$ | 匹配行以 world 結尾。 |
go?gle | 代表前一個字元出現零次或一次 (0 或 1 次),匹配 ggle、gogle 等,等同於 {0,1} 。 |
go*gle | 代表前一個字元出現任意次數 (0 次以上),匹配 ggle、gogle、google 等,等同於 {0,} 。 |
go+gle | 代表前一個字元至少出現一次 (1 次以上),匹配 gogle、google 等,等同於 {1,} 。 |
go{m}gle | 指定前一個字元出現 m 次。 |
go{m,}gle | 指定前一個字元出現 m 次以上。 |
go{m,n}gle | 指定前一個字元出現次數,m~n 之間的次數。 |
A\|B | 匹配 A 或 B 字串,true\|false 匹配 true 或 false 字串。 |
\ | 下一個字符標記為特殊字元、或原義字元。\? 匹配 ? (因為 ? 本身在正規表達式裡是代表不同意思) |
() | 一個子表達式的開始和結束,提取子表達式字串供之後使用。 |
$1 | 第一組使用 () 匹配的部分,$2 代表第二組、$0 代表完整匹配的內容。 |
特別序列 (Special Sequences):
符號 | 說明 |
---|---|
\d | 所有數字,等同於 [0-9] 。 |
\D | 所有非數字,等同於 [^0-9] 。 |
\w | 所有字母、數字、底線,等同於 [A-Za-z0-9_] 。 |
\W | 所有非字母、數字、底線,等同於 [^A-Za-z0-9_] 。 |
\s | 任意空白字元,等同於 [ \f\n\r\t\v] 。 |
\S | 任意非空白字元,等同於 [^ \f\n\r\t\v] 。 |
\n | 換行字元。 |
\t | tab 字元。 |
\b | 單字的邊界。 |
\B | 非單字的邊界。 |
*
和 +
是貪婪的(匹配越多越好),可以在後方加上 ?
使用非貪婪模式,例如有一個 HTML 字串 <h1>正規表達式</h1>
:
<.*>
會匹配到 <h1>正規表達式</h1>
;<.*?>
會匹配到 <h1>
和 </h1>
。
為了寫這篇文章在查找正規表達式時,發現有一種 Lookahead 和 lookbehind 語法,感覺也很實用。
符號 | 說明 |
---|---|
x(?=y) | zero-width positive lookahead assertion,匹配 x,並且後方是 y。 |
x(?!y) | zero-width negative lookahead assertion,匹配 x,並且後方不是 y。 |
例如有一字串 Java JavaScript JavaBeans
:Java(?=Script)
會匹配到 JavaScript
的 Java
;Java(?!Script)
會匹配到 Java
和 JavaBeans
的 Java
。
符號 | 說明 |
---|---|
(?<=y)x | zero-width positive lookbehind assertion,匹配 x,並且前方是 y。 |
(?<!y)x | zero-width negative lookbehind assertion,匹配 x,並且前方不是 y。 |
例如有一字串 Script JavaScript TypeScript
:(?<=Java)Script
會匹配到 JavaScript
的 Script
;(?<!Java)Script
會匹配到 Script
和 TypeScript
的 Script
。
這邊超級推薦一個線上網頁工具,方便我們嘗試正規表達式:regex101
基本操作
在 VS Code 內要使用 尋找/取代 功能,可以使用快捷鍵 Ctrl + f
叫出 尋找/取代 視窗,或從左上角功能列打開 編輯 > 尋找/取代。
在輸入框可以使用 Ctrl + Enter
插入換行,在 "尋找" 的輸入框可用上下鍵查看歷史紀錄。
因為本篇主要說明正規表達式的尋找與取代,因此 "使用正規表達式" 的那顆按鈕要啟用。
題外話:
stack overflow 上這篇回答提到,VS Code 的正規表達式是使用 JavaScript 的 RegEx engine。
(這邊指的是以上說明的 "尋找/取代 小工具",左邊文件欄的又不太一樣,不過基本常用的正規表達式語法都是有支援的)
特殊案例
以下列出一些較特殊的案例給各位參考。
多個連續的空白換成一個
先來個簡單的,假如要將多個連續空白換成一個空白:
使用 \s+
查找,取代成 :
大 家 好 嗎?
// 取代後會變成
大 家 好 嗎?
找出 Java 而不是 Javascript
假設有一個句子:difference between Javascript and Java.
直接使用 Java
去搜尋會找到 Javascript
的 Java
和 Java
。
但我其實只想要找出 Java
這個單字。
這時候就可以使用 \b
(單字的邊界)來尋找:\bJava\b
保留原字串內容 $
正規表達式內使用 ()
可以將這部分提取出來,在取代的部分就可以使用 $1
指第一個字串、$2
指第二個字串 ($0
指匹配的全部)。
舉個例子,我們想把 HTML 語法內的 h2 全部替換為 Markdown 語法的標題(##
),當然標題的字串要留著。
使用 <h2>(.+?)<\/h2>
查找,取代成 ## $1
,
因此 <h2>標題一</h2>
取代後會變成 ## 標題一
。
* 因為 </h2>
內的斜線在正規表達式內是有其他功能,因此想要比對斜線,前方需要加上反斜線 \
來將其標示為一般字串。
* 在 ()
內還有使用 ?
來使用非貪婪模式,避免如果一行字串出現兩個 <h2></h2>
會有問題。
替換英文大小寫
符號 | 說明 |
---|---|
\u | 大寫一個字元。 |
\l | 小寫一個字元。 |
\U | 大寫匹配組的全部字元。 |
\L | 小寫匹配組的全部字元。 |
使用 (hello)(.*)
查找,取代成 \l$1\U$2
,
因此 Hello world
取代後會變成 hello WORLD
。
將日期 2023/07/01 轉換為 2023年07月01日
我們想把日期中間的斜線替換成 "年"、"月"、"日"。
使用 ()
group 將年、月、日的數字抽取出來,再使用 "年"、"月"、"日" 去替換掉。
使用 (\d{4})\/(\d{2})\/(\d{2})
查找,取代成 $1年$2月$3日
,
因此 2023/07/01
取代後會變成 2023年07月01日
。
日期字串補上 0
同樣是日期但不同操作,我們想把日期字串 2023/5/1
補上 0 變成 2023/05/01
,當然他如果原本就是兩位數,則不需要補 0。
使用 /(\d{1})(?=[\D\n])
查找,取代成 /0$1
,
因此 2023/5/10
取代後會變成 2023/05/10
。
去除相鄰的重複英文單字
這個範例是我們想把相鄰的重複英文單字找出來,並取去除掉,只留下一個就好。
使用 \b(\w+)\s+\1\b
查找,取代成 $1
,
因此 The the quick brown fox jumps over the lazy dog dog.
會被替換成 The quick brown fox jumps over the lazy dog.
。
* \b
:單字的邊界
* (\w+)
:一個英文單字
* \s+
:一個或多個空格
* \1
:重點,匹配與第一組(即前面的 (\w+)
)相同的單詞。
後續如果還有遇到比較特別的例子,我還會再補上~
結語
本來寫這篇文章前,想說舉幾個特殊用法就好,結果資料查著查著,就不小心把正規表達式(Regular Expression)的用法也整理出來了🤣
算了,剛好也可以給未來的我參考。
本篇文章所說明的概念,使用 Visual Studio IDE 或其他編輯器也是大同小異。
歡迎追蹤『IT空間』FB 粉專,取得最新發文通知🔔
參考:
正規表達式 | MDN Web Docs
regex101
VS Code 官方使用尋找取代說明
正規表示式(Regular Expression)| HackMD
你所害怕的事情,從來不會如你想像中的那般嚴重。
你自己在腦海裡所勾勒出來恐懼的影像總是會比實際情況糟的多。—— 史賓賽強森
🔻 如果覺得喜歡,歡迎在下方獎勵我 5 個讚~