0%

Regular Expression 正則表達式 - 初探

維基百科陳述如下:

正規表示式(英語:Regular Expression,常簡寫為 regex、regexp 或 RE),又稱正規表達式、正規表示法、規則運算式、常規表示法,是電腦科學的一個概念。正規表示式使用單個字串來描述、符合一系列符合某個句法規則的字串。在很多文字編輯器裡,正則表達式通常被用來檢索、替換那些符合某個模式的文字。

簡單來說正則表達式並不是程式語言,是一種「字串樣式規則」的「表示法」,用來判斷字串的方法,並且使用一套專屬自己的符號表式法,讓開發者可以快速搜尋、取代、刪除以及測試字串是否符合規則,大多數程式語言都有支援正則表達式來處理字串。

正則入門教學與測驗網站 RegexOne

基本語法

正則表達式通常會稱為一個 pattern,是用來描述或匹配符合某樣式規則的字串。而匹配字串最簡單的方式是把所有可能性都列出,透過簡潔有效率的語法和符號來描述 pattern,可以優雅地找到想要的字串。

要匹配同一組字串有很多種寫,但最重要的原則能簡單易讀,而不是寫得很長結果連自己過了一段時間回頭都看不懂,那就不太好了。

pattern 通常由字符常量 (literal character constants) 和符號運算子 (operator symbols) 組成。

以下說明可以同步使用 regex101 此網站做練習,比較知道下方舉例的效果。

一個 pattern 會由以下幾個常見的元素組成:

字元

也就是單純照著字面意思來做匹配。

例如:
可以透過輸入 dog 來找到 dog 的字串, hello 可以找到 hello 的字串。

[ ] 包含字元種類

因為在實務中,不可能找字串都完全使用輸入文字來找,會非常耗時又沒效率,而且失去使用正則的意義,故要匹配上方條件的字串會使用一個中括號,裡面輸入[a-z] 代表匹配出 a-z 的字符。

[^] 不包含字元種類

在中括號裡面加一個 caret 符號,代表除了字串裡面的文字都是不需要匹配的。

例如:
要找一個人的帳號 abc123,但我要排除英文字符,只需要數字,此時就可以寫 [^abc],在匹配時只會找出數字。

| (或 or)

管線符號,用來表示所有可能的條件,並將其分隔開。

例如:
想找到 tom 或是 tim 這兩組字串,使用字串來找可以使用 tom | tim,來找出匹配 tom 或是 tim 的字串。

群組 ()

使用小括號 () 來表示作用範圍或是其優先順序。

例如:
要找到有 dogcat 這兩組字串或是優先找到有包含這兩組字串的時候,就可以輸入(dog | cat) 來優先找出匹配有 dog 或是 cat 的字串,這在找一些複雜情境時會很好用。

量詞

接在字符串或群組後面,表示某些條件要出現的「次數」,常用的量詞有:

^ 起始 $ 結束

這兩個很長共用也常分開使用,但觀念雷同,故一起介紹, ^ 代表字符代表的起始位置。

例如:
我今天要找通訊錄中開頭有 a 的同事,像是 Alex,Allen,Alice,Amy…等,就可以寫 ^a,就會找出名字是 a 開頭的字符;相對的我要找結尾有 n 的同事,像是 Allen,Sean,Brian…等。就可以寫 n$,就會找出結尾是 n 的字符。

+ 一次到無限次

在指定字符後寫上加號,就會從該字符後只要有出現往後盡量匹配跟條件相符的結果。

例如:
要匹配的項目是 aaabbbaaaccccccccc,條件寫 a+,就會盡量匹配只要出現一個 a 的字符,若中間有匹配條件外的中斷匹配,會在匹配條件後繼續匹配。像這邊的結果就會找到一開始的 aaa,中間 bbb 中斷了匹配,但會再繼續從 bbb 後匹配到 aaaa 出現一次以上的找出來。

* 零次到無限次

+ 很像,只是會從沒有出現的字符開始匹配,用下圖表示會更清楚。

? 從零次到 1 次

匹配條件可有可無,但如果有,就只能一次。

例如:
balloon 這個字串,有兩個練續的 o 字符,如果匹配條件是 lo?,代表我要找的條件一定要有 l,但 o 可有可無。

{min, max} 最少連續出現幾次與最多連續出現幾次

這個匹配條件最常用的情境,其中一個是在設定帳號或密碼的長度,會要求最少要多少字符以上,最多要多少字符。
例如:
匹配條件要是英文字符,且最少 6 字符,最多 16 字符。就可以這樣寫 [a-z]{6,16}

\ 跳脫字元

就是把一些特殊符號轉成正則可以匹配的條件。
例如:
網站會有一些符號,可以透過跳脫字元將其轉成可匹配的條件。像是 option:item,匹配條件可以是:[a-z]{3,}\:[a-z]{1,}。max 的直沒有寫,就是無限長。

以上就是正則表達式的基本介紹,在寫 pattern 的時候會發生很多 bug,而網路上有很多寫好的 pattern,但如果看不懂的話又貿然使用,複雜的正則式會造成無線迴圈造成把 CPU 的資源吃光。

參考資料