| 貪婪 | 懶惰 | 佔有優先 | 說明 |
|---|---|---|---|
* | *? | *+ | 0 次或多次 |
+ | +? | ++ | 1 次或多次 |
? | ?? | ?+ | 0 次或 1 次 |
{n} | {n}? | {n}+ | 恰好 n 次 |
{n,} | {n,}? | {n,}+ | 至少 n 次 |
{n,m} | {n,m}? | {n,m}+ | n 到 m 次 |
string input = "contentmore";
// 貪婪:盡可能多比對
Regex.Match(input, "<.+>").Value; // "contentmore"
// 懶惰:盡可能少比對
Regex.Match(input, "<.+?>").Value; // ""
// 佔有優先:不回溯,效能最好但可能比對失敗
Regex.Match(input, "<.++>").Value; // 比對失敗 (無法回溯配合 >)
回溯機制與效能陷阱
貪婪量詞會先吞噬整字串,再逐字回溯嘗試滿足後續模式。複雜巢狀量詞 (如 (a+)+) 面對惡意輸入會導致災難性回溯 (ReDoS)。懶惰量詞減少回溯但增加前瞻開銷。佔有優先量詞 *+ ++ 禁止回溯,適合明確不需回溯的模式。
最佳實務
- 預設使用懶惰量詞
*? +? 避免過度比對
- 明確知悉不需回溯時使用佔有優先
++ *+
- 避免巢狀量詞,改用字元類別或定位符限制範圍
- 長字串處理設定
RegexOptions.Compiled 或使用 Regex.MatchTimeout 防禦 ReDoS



本文對應《叩響 C# 之門》第 20.5 節教學內容