在 RPA(流程自動化)的世界裡,我們花了 80% 的時間在處理「非結構化數據」。無論是從 PDF 發票中抓取總金額,還是從混亂的 Email 裡提取訂單編號,文字處理永遠是最大的痛點。
你是否曾經寫過這種邏輯?
「先找到 "@" 的位置,然後往左抓 5 個字,再往右抓直到遇到空白鍵...」
以上這種substring, split作法也很常見,但這可能使得資料清洗變得攏長又複雜,最怕的是下次你回來看程式碼忘記這一小段的區塊是在處理什麼樣的邏輯。現在就有另一種優雅又精準的方式一樣能找到你想要的字串:正則表達式(Regular Expression,簡稱 Regex)。
在使用時,需要遵照它的語法規則,而在本社之前的文章中,很清楚透過實例介紹了使用情境以及如何使用(VBA及PAD)會計人為什麼要學正則表達式? 。還有另一篇文章也幫大家整理了很多很實用的正則表達式語法給會計人的Excel正則表達式小抄 ,歡迎參考取用!
而在本篇文章主要想要探討的是正則表達本身的語法,當未來大家看到語法時可以有個概念且更好讀懂別人的Regex。(但以我自己來說,如果真的湊不出來,跟AI講你的需求之後,它就會給你Regex的語法了,現代人的偷吃步)
Regex語法
正則可以分成這四種類別組合,主要會互相疊加使用找到特定字串。
- 字元(Characters)
- 量詞 (Quantifiers)
- 定位 (Anchors)
- 群組與邏輯 (Groups & Logic)
字元(Characters):找什麼?
\d:代表一個數字,d代表Digit的意思,包含0-9。\w:代表一個文字,w代表Word的意思,包含英文大小寫、底線。\s:代表一個空白,s代表space的意思,包含空白鍵、Tab。.:代表任意一個字元,除了換行以外通吃,是強大的萬用符。
範例:如果想抓格式為 "A1" 的編號(一個字加一個數字) 你的 Pattern 就是:\w\d量詞 (Quantifiers):找幾個?
剛剛的 \d 只能抓一個數字,如果我要抓年份 "2023" 怎麼辦?寫 \d\d\d\d 太累了。這時候我們需要「量詞」來修飾它左邊的那個規則。
*:0次或無限多次(有無皆可)。+:1次或無限多次(至少要有一個)。?:0次或1次(可有可無)。{n}:固定出現N次。{n,m}:出現N次到M次之間。
小範例:
抓年份 (4位數字):\d{4}
抓訂單編號 (長度不固定的數字串):\d+
另外,很類似的* + ?想特別拉出來比較彼此差異性:
讓我們用一個具體的例子:抓取單字 "Google",但這單字可能會被打錯或變形。
* (星號):0次或無限多次(有無皆可)
適合用在:可能會出現的雜訊,例如空白鍵、裝飾符號。
- Pattern:
Go*gle(代表中間的o可以完全沒有,也可以有很多) Gogle→ OGoogle→ OGooogle→ OGgle→ O (符合! 即使沒有 o,它也接受)
- Pattern:
RPA 應用: 處理髒亂資料的空白鍵
A\s*B。 用來匹配 "A B"。有時候冒號前後沒有空白,有時候有 5 個空白。用\s*就能通吃這兩種情況。
+ (加號):1次或無限多次(至少要有一個)
適合用在:資料的核心部分,例如數字、金額、帳號。你不會希望抓到「空」的東西。
- Pattern:
Go+gle(代表中間的o至少要有一個) Gogle→ O (有一個 o,符合)Google→ O (有兩個 o,符合)Gooogle→ O (有很多 o,符合)Ggle→ X (失敗! 因為完全沒有 o)
- Pattern:
RPA 應用: 抓取金額
\d+。 如果你用\d*去抓金額,萬一游標停在兩個空白鍵中間,\d*會覺得「0 個數字也符合」,結果回傳空字串給你,導致程式報錯。抓具體資料時,請務必用+。
? (問號):0次或1次(可有可無)。
適合用在:拼寫差異、單複數、Http/Https。
- Pattern:
Go?gle(代表中間的o最多只能有一個,或者沒有) Ggle→ O (0 個 o,符合)Gogle→ O (1 個 o,符合)Google→ X (失敗! 2 個 o 太多了,超過範圍)
- Pattern:
RPA 應用: 網址
https?。http符合,https也符合。這在抓取網址時是標配寫法。 還有英文單複數files?,可以同時匹配 "file" 和 "files"。
定位 (Anchors):在哪裡?
^:指定在字串的開頭,要找的字串必須出現在這行字最前面。$:指定在字串的結尾,要找的字串必須出現在這行字最後面。\b:單字邊界,b代表Boundary,單獨取得\b內的內容,前後不會再抓其他東西。
範例:假如你要搜尋數字100,\b100\b。它就只會抓獨立存在的"100"而不會抓到"2100"或"0910012345"裡面的100。
範例2:驗證手機號碼(台灣手機號碼)
Pattern設計:^\d{10}$,從頭跟結束時都要是數字,且數字只能10碼。
結果:0912345678-> Pass0912345678(有空白) -> Fail(後面沒有立刻結束,包含到空白)Tel:0912345678-> Fail (開頭不是數字)
群組與邏輯 (Groups & Logic):建立結構
當結構變複雜時,可以使用群組把所有語法包起來,設定篩選範圍。
[]集合(Set):在範圍內有符合一個的。
例如[ABC]代表這個字串有A或B或C。
常見用法:[A-Z]有出現所有大寫字母都符合、[a-z]亦相同、[0-9]有出現數字0-9都符合。
|或(Or):有符合|左邊或右邊規則即可。
例如Cat|Dog代表,有符合Cat或Dog都會被匹配到。
()群組(Group):有兩種功能。1. 邏輯打包 2. 把特定的部分提取出來就好。
範例1:想抓笑聲 "hahaha",長度不限。
若使用ha+,會變成h只有一個,a可以有很多個。也就是會抓到haaaaa。(ha)+,而使用()就是限定括號內會一起出現多次,就會抓到"hahaha"。
範例2:有一行文字Order Number: 2023999 created.,你只想把號碼2023999存進變數。
如果使用Order Number: \d+,你會抓到Order Number: 2023999。變成你得在用程式去除掉Order Number: 跟可能多餘的空白部分。
這時候如果你用Order Number: (\d+),Regex知道你只想抓括號裡面的字串,就可以更有效率。
小工具:
這邊介紹一個小工具,如果你自己設計出了正則表達,想要測試是不是正常運作可以到這個網站做測試或者看到別人的正則可以直接貼進去看效果。這個工具算是蠻實用也普遍被熟知的~
小結語:
這次整理又再一次統整跟複習,透過這篇文章希望各位有更了解正規表達式的“規則”,之後看到別人有寫正則的時候也不妨去拆解看看他們想要抓什麼值~但就像前面有提到,現在有AI真的很方便,真的想不出來AI都可以查得到唷!
動動腦
假設要從這句話抓出 名字: Client Name: [Jason] Confirmed.
請試試看,你會怎麼把 [ 和 ] 當作定位點,但只抓出 Jason?
- 先寫出「全貌」:
\[\w+\](這會抓到[Jason],含括號) - 把要的「肉」包起來:
\[(\w+)\]
這樣寫,機器人就會知道:
- Full Match (全貌):
[Jason] - Group (提取):
Jason
下篇再見~










