正規表示式
系列【正規表示式】──一次找出不同日期
上一篇「系列【正規表示式】──AI 時代依然實用的知識」介紹了正規表示式最基本的概念:不是搜尋某一個固定的字串,而是用「文字的模式」來搜尋。
這一次,我們再往前一步。
假設文件中出現了這些日期:
年、月、日都不一樣。
如果用一般搜尋,就得分別搜尋每一個日期;但使用正規表示式,就可以用一個表示式一次把它們找出來。
這一篇不會先丟出完成版叫大家硬背,而是沿用上一篇學過的內容,一小段一小段把表示式組起來。
先找出「年」
上一篇我們已經看過,若要搜尋「4 位數字+年」,可以寫成:
\d{4}年
拆開來看:
- \d = 1 個數字
- {4} = 前面的項目剛好重複 4 次
年= 文字「年」
把它套到剛才的例子,就會找出下面這些部分:
這裡算是上一篇的複習。
接下來,把「月」也加進去。
再把「月」接上去
月份可能是:
9月
也可能是:
12月
也就是說,數字可能有 1 位,也可能有 2 位。
上一篇介紹過,若要表示「數字出現 1 次以上」,可以寫成:
\d+
所以直接接在剛才的表示式後面:
\d{4}年\d+月
這次搜尋到的範圍就會再長一點:
現在已經愈來愈像完整的日期了。
最後加上「日」
「日」也一樣,可能是:
1日
也可能是:
31日
所以再加上一組 \d+:
\d{4}年\d+月\d+日
這樣就能把整個日期一起找出來。
其實做到這裡,這篇文章原本設定的目標就已經達成了。
這裡有一個很值得記住的觀念:
同一個搜尋目的,正規表示式不一定只有一種正確寫法。
以這次的日期為例:
\d{4}年\d+月\d+日
本身就是一個完全可以使用的答案。
要搜尋同一類字串,常常可以寫出不同的正規表示式。有些寫法比較寬鬆,有些會把條件限制得更細;有些比較短,有些雖然長一點,但意圖更清楚。
重點並不是找到「唯一正確的公式」,而是能不能把自己想找的文字模式表達出來。
接下來,我們就在這個已經能用的表示式上,再多加一點條件。
把「月」和「日」的位數寫得更明確
實際的日期可能寫成:
2026年9月1日2026年09月01日2025年12月31日
也就是說,月和日都可能是 1 位數,也可能是 2 位數。
如果把條件說得更精確一點,我們真正要找的是:
「月和日各由 1 或 2 個數字組成」。
假設寫成:
\d{2}
那就只能找出 2 位數的內容,例如 09 或 31,卻找不到 9 或 1。
這時就可以用今天的新語法:
{1,2}
{1,2}──重複 1 次到 2 次
上一篇介紹的:
{4}
代表「前面的項目剛好重複 4 次」。
同樣的概念,
{1,2}
表示:
前面的項目至少出現 1 次,最多出現 2 次。
所以:
\d{1,2}
就是:
1 位或 2 位數字。
把它放到月和日的位置,便得到:
\d{4}年\d{1,2}月\d{1,2}日
拆開來看就是:
| 表示式 | 意義 |
|---|---|
| \d{4} | 4 位數字 |
年 | 文字「年」 |
| \d{1,2} | 1 位或 2 位數字 |
月 | 文字「月」 |
| \d{1,2} | 1 位或 2 位數字 |
日 | 文字「日」 |
也就是:
4 位數字+年+1~2 位數字+月+1~2 位數字+日。
圖 1 想找的日期各部分,與 \d{4}年\d{1,2}月\d{1,2}日 各元件之間的對應關係。
現在再比較一次:
\d{4}年\d+月\d+日
和
\d{4}年\d{1,2}月\d{1,2}日
對這篇文章列出的日期來說,兩個都搜尋得到。
後者只是多表達了一個條件:月和日各有 1~2 位數字。
不是前者錯、後者才對。兩個都可以是正確答案。
要把條件寫到多細,取決於實際資料和搜尋目的。正規表示式很常見的做法,就是先寫出「可以達到目的」的版本,再視需要縮小範圍,或反過來把表示式簡化。
找得到「日期格式」,不代表它真的是有效日期
還有一點需要注意。
我們剛才寫的:
\d{4}年\d{1,2}月\d{1,2}日
也會比對到:
2026年99月99日
當然,99 月和 99 日都不存在。
原因是正規表示式在看的只是文字模式。
我們的條件只是:
4 位數字後面有「年」,接著是 1~2 位數字和「月」,最後再接 1~2 位數字和「日」
它並不知道一年有幾個月,也不知道 2 月有幾天。
當然,我們還可以加入更多條件,把搜尋範圍限制得更嚴格;但表示式也會跟著變複雜。
在翻譯或 QA 的實務中,很多時候只要先把可能的候選項目一次找出來,再人工確認,就已經足夠。
所以真正需要考慮的不是「能不能寫出最嚴密的正規表示式」,而是:這次的工作到底需要多精確?
在翻譯與 QA 工作中有什麼用?
這次的表示式很簡單,但在長文件或大量內容中其實相當實用。
例如要確認文件內的日期格式是否統一,就可以用正規表示式一次找出多個不同日期,而不必事先知道每一個確切日期。
在支援正規表示式的搜尋或篩選功能中,也可以藉此快速縮小需要檢查的範圍。
memoQ 的尋找與取代,以及翻譯編輯器中的篩選等功能,也可以使用正規表示式。
這也是為什麼正規表示式和翻譯、QA 工作很合拍:我們可以描述「想找的文字長什麼樣子」,而不需要事先知道那段文字的完整內容。
還是不需要背完整公式
如果只看到:
\d{4}年\d{1,2}月\d{1,2}日
一開始可能會覺得有點複雜。
但回頭看看這篇文章實際做了什麼:
我們先從:
\d{4}年
開始,再加上月份:
\d{4}年\d+月
接著加上「日」:
\d{4}年\d+月\d+日
做到這裡,其實搜尋已經可以正常完成。
之後只是因為想把「月和日各有 1~2 位」也寫進條件裡,所以改成:
\d{4}年\d{1,2}月\d{1,2}日
一步一步拆開來看,並沒有做什麼特別困難的事。
而且,也不需要把其中某一個版本當成唯一的「標準答案」背起來。
同一個搜尋目的,本來就可能有好幾種正規表示式寫法。
有時候簡單、寬鬆一點的表示式就夠用了;有時候則需要把條件寫得更細。
真正重要的是,把想搜尋的字串拆成小元件,再根據工作需求把這些元件組成適合的模式。
下一篇:從搜尋進一步到「取代」
這次我們學會了怎麼一次搜尋不同的年月日。
下一篇會再往前一步,從「搜尋」進入「取代」。
例如,我們可以把:
2026年9月1日
重新排列成:
9/1/2026
或其他順序。
要做到這件事,就必須讓正規表示式先「記住」年、月、日各是哪一段,之後才能在取代時重新拿出來排列。
下一篇就會介紹這個非常實用的功能:擷取群組(capture groups)。