量詞
量詞回答「前面那一塊要出現幾次」。它作用在緊鄰的前一個原子:一個字、一個 \ 序列、一個 [...],或一組 (...)。
常用量詞
| 量詞 | 次數 |
|---|---|
? |
0 或 1 |
* |
0 次以上 |
+ |
1 次以上 |
{n} |
剛好 n 次 |
{n,} |
至少 n 次 |
{n,m} |
n 到 m 次(含) |
import re
text = "color colour colouur"
print(re.findall(r"colou?r", text)) # ['color', 'colour']
print(re.findall(r"\d{4}", "2026-09-15")) # ['2026']
print(re.findall(r"\d{2,4}", "9 15 2026")) # ['15', '2026']
colou?r 的 ? 只作用在 u,所以 color 與 colour 都會中,colouur 不會。
貪婪是預設
* + {n,m} 預設能吃就多吃,再往回吐到後面的模式也能成立:
import re
html = "<b>粗</b> 與 <i>斜</i>"
print(re.findall(r"<.*>", html)) # ['<b>粗</b> 與 <i>斜</i>'] 一次吃到最後一個 >
print(re.findall(r"<.*?>", html)) # ['<b>', '</b>', '<i>', '</i>']
在量詞後面加 ? 變成懶惰(non-greedy):*? +? ?? {n,m}?。抽取 HTML 標籤這種「最短的一對 <>」才需要它。
不要用 regex 當 HTML 剖析器
上面只是示範貪婪。真實 HTML 請用專用函式庫。巢狀、屬性、註解都會讓模式很快失真。
量詞作用範圍
import re
print(re.findall(r"ha+", "ha haha haaa")) # ['ha', 'ha', 'ha', 'haaa']
print(re.findall(r"(ha)+", "haha haaa")) # findall 回傳最後一次捕獲
print(re.findall(r"(?:ha)+", "haha haaa")) # ['haha', 'ha']
要重複「一整段」,先括起來再定量詞。不需要捕獲就用 (?:...)。