本篇重點
- 說明擴充型分組的用途
- 說明非捕獲分組
?:的用途 - 說明先行斷言
?=、?!、後行斷言?<=、?<!的用途與差異 - 非捕獲分組有匹配但不記錄分組結果
- 斷言只檢查條件不匹配任何內容
擴充型分組
以 (? 開頭,屬於正規表達式的「擴充型分組(Extended Group)」語法,主要用途是改變群組行為或設定匹配條件。
| 類型 | 語法 | 名稱 | 是否匹配字元 | 是否捕獲內容 |
|---|---|---|---|---|
| 一般分組 | (pattern) | capturing group | ✅ | ✅ |
| 非捕獲分組 | (?:pattern) | Non-capturing group | ✅ | ❌ |
| 斷言(先行/後行) | (?=...)、(?!...)、(?<=...)、(?<!...) | Lookaround assertion | ❌ | ❌ |
非捕獲分組
非捕獲分組(Non-capturing Group)是讓正規式結構化或重複某段規則,但不捕獲分組結果,仍然會參與實際的匹配過程,只是不會佔用群組索引或儲存結果。
使用時機
(?:pattern)
建立條件組合但不希望影響
$1、$2群組索引。群組僅為結構性用途(如限定重複次數或選擇):
限制重複次數
你需要讓一段模式重複多次時,必須用括號把那段包起來:
js 1
2const regex = /(?:ab){2}/;
console.log("abab".match(regex)); // ["abab"]這裡
(ab){2}表示「ab 重複兩次」,若不用括號/ab{2}/則表示「a 後面接兩個 b」→ “abb”,使用(?:ab){2}而不是(ab){2}是因為不需要捕獲 “ab”,只是想讓整段重複。選擇(alternation)用途
當你用 |(或條件)時,常需要把多個選項包起來:
js 1
2
3const regex = /^(?:cat|dog)s?$/;
console.log("cats".match(regex)); // ["cats"]
console.log("dog".match(regex)); // ["dog"](?:cat|dog)表示「cat 或 dog」,s?表示可選的複數 s,這樣寫是為了讓正則語法正確運作,並且不需捕獲 “cat” 或 “dog”。
範例
1 | const str = "2025-11-05, 2024-07-20"; |
說明:
年份以 (?:...) 包起來,只是為了表達結構,不需要在結果中取出,因此不建立捕獲群組,但有匹配字元。
斷言
斷言(Assertions, Lookaround)屬於零寬度匹配(zero-width match),也就是只檢查字串中「某個位置的前後條件」,不消耗字元、也不會出現在結果中。
斷言可分為四種:
| 類型 | 語法 | 檢查方向 | 條件 |
|---|---|---|---|
| 正向先行斷言 | (?=pattern) | 後方 | 必須符合 |
| 負向先行斷言 | (?!pattern) | 後方 | 不得符合 |
| 正向後行斷言 | (?<=pattern) | 前方 | 必須符合 |
| 負向後行斷言 | (?<!pattern) | 前方 | 不得符合 |
正向先行斷言
(?=pattern) 檢查某位置後方是否符合指定條件。
若符合,該位置可被匹配,但 pattern 本身不會納入結果。
範例
1 | const str = "商品A 100元, 商品B 200元, 商品C 300日圓"; |
說明
匹配「後面接著『元』」的數字,排除「日圓」的數字。
負向先行斷言
(?!pattern) 檢查某位置後方不得符合指定條件。
範例
1 | const str = "apple pie, apple tart, apple juice"; |
說明
/apple(?!\start)/g的\s是空白的意思。- 僅匹配後方不是 “ tart” 的 “apple”。
正向後行斷言
(?<=pattern) 檢查某位置前方是否符合指定條件,若符合,即可從該位置開始匹配。
範例
1 | const str = "JPY300, USD120, USD500"; |
說明
只取出「前方是 USD」的數字。
負向後行斷言
(?<!pattern) 檢查某位置前方不得符合指定條件。
範例
1 | const str = "VIP123, GUEST456, USER789"; |
說明
斷言只檢查匹配開頭的位置,並不會讓整段文字「整體排除」,因此會在 "VIP123" 的第 4 個位置(2)發現條件成立(前方不等於 VIP),開始匹配數字,得到 "23"。
非捕獲分組與斷言的差異
| 比較項目 | 非捕獲分組 (?:pattern) | 斷言 ( ?= / ?! / ?<= / ?<! ) |
|---|---|---|
| 是否參與匹配 | ✅ 有實際匹配字元 | ❌ 不匹配字元(零寬度) |
| 是否捕獲內容 | ❌ 不捕獲 | ❌ 不捕獲 |
| 主要功能 | 結構化表達式、不記錄群組 | 檢查前後條件 |
| 實際應用範例 | 建立非捕獲群組以控制重複或選擇 | 根據上下文條件限制匹配範圍 |
範例
1 | const str = "Price: $100, €200, $300"; |
- 非捕獲分組 → 有匹配、但不記錄分組結果。
- 斷言 → 只檢查條件、不匹配任何內容。
結論
非捕獲分組與四種斷言語法是讓正規表達式更具彈性的重要工具:
(?:pattern):非捕獲分組,用於結構化匹配但不取值。(?=pattern)、(?!pattern):先行斷言,用於判斷後方條件。(?<=pattern)、(?<!pattern):後行斷言,用於判斷前方條件。



